summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2017-08-15 13:39:50 +0800
committerruki <[email protected]>2017-08-15 13:44:27 +0800
commitb92d83c523045d7e8b716dc0610b88b0d357575f (patch)
tree161cebb851686c2b140ca53451089d4faca307d0
parentf7083cb5c14a5cf84c9c0ccd07891a251ec39b35 (diff)
remove some unused codes
-rw-r--r--core/src/luajit/dynasm/dasm_arm.h456
-rw-r--r--core/src/luajit/dynasm/dasm_arm.lua1125
-rw-r--r--core/src/luajit/dynasm/dasm_mips.h416
-rw-r--r--core/src/luajit/dynasm/dasm_mips.lua953
-rw-r--r--core/src/luajit/dynasm/dasm_ppc.h412
-rw-r--r--core/src/luajit/dynasm/dasm_ppc.lua1249
-rw-r--r--core/src/luajit/dynasm/dasm_proto.h83
-rw-r--r--core/src/luajit/dynasm/dasm_x64.lua12
-rw-r--r--core/src/luajit/dynasm/dasm_x86.h471
-rw-r--r--core/src/luajit/dynasm/dasm_x86.lua1945
-rw-r--r--core/src/luajit/dynasm/dynasm.lua1094
-rw-r--r--core/src/luajit/etc/luajit.188
-rw-r--r--core/src/luajit/etc/luajit.pc25
-rw-r--r--core/src/sv/test/CMakeLists.txt27
-rw-r--r--core/src/sv/test/comp.c333
-rw-r--r--core/src/sv/test/match.c357
-rw-r--r--core/src/sv/test/range.c200
-rw-r--r--core/src/sv/test/semver.c106
-rw-r--r--core/src/sv/test/semvers.c115
-rw-r--r--core/src/sv/test/usage.c46
-rw-r--r--core/src/sv/test/utils.c102
-rw-r--r--core/src/sv/test/version.c236
-rw-r--r--core/src/sv/test/xmake.lua45
-rw-r--r--core/src/tbox/src/tbox/asio/asio.h36
-rw-r--r--core/src/tbox/src/tbox/asio/deprecated/aice.h484
-rw-r--r--core/src/tbox/src/tbox/asio/deprecated/aico.c1082
-rw-r--r--core/src/tbox/src/tbox/asio/deprecated/aico.h733
-rw-r--r--core/src/tbox/src/tbox/asio/deprecated/aicp.c596
-rw-r--r--core/src/tbox/src/tbox/asio/deprecated/aicp.h180
-rw-r--r--core/src/tbox/src/tbox/asio/deprecated/aioe.h76
-rw-r--r--core/src/tbox/src/tbox/asio/deprecated/aioo.c59
-rw-r--r--core/src/tbox/src/tbox/asio/deprecated/aioo.h72
-rw-r--r--core/src/tbox/src/tbox/asio/deprecated/aiop.c326
-rw-r--r--core/src/tbox/src/tbox/asio/deprecated/aiop.h156
-rw-r--r--core/src/tbox/src/tbox/asio/deprecated/asio.h44
-rw-r--r--core/src/tbox/src/tbox/asio/deprecated/deprecated.h35
-rw-r--r--core/src/tbox/src/tbox/asio/deprecated/dns.c571
-rw-r--r--core/src/tbox/src/tbox/asio/deprecated/dns.h104
-rw-r--r--core/src/tbox/src/tbox/asio/deprecated/http.c1770
-rw-r--r--core/src/tbox/src/tbox/asio/deprecated/http.h259
-rw-r--r--core/src/tbox/src/tbox/asio/deprecated/impl/aicp_aiop.c1795
-rw-r--r--core/src/tbox/src/tbox/asio/deprecated/impl/aicp_file.c238
-rw-r--r--core/src/tbox/src/tbox/asio/deprecated/impl/prefix.h323
-rw-r--r--core/src/tbox/src/tbox/asio/deprecated/prefix.h139
-rw-r--r--core/src/tbox/src/tbox/asio/deprecated/ssl.c1366
-rw-r--r--core/src/tbox/src/tbox/asio/deprecated/ssl.h287
-rw-r--r--core/src/tbox/src/tbox/asio/prefix.h33
-rw-r--r--core/src/tbox/src/tbox/container/element/prefix.h1
-rw-r--r--core/src/tbox/src/tbox/container/iterator/prefix.h1
-rw-r--r--core/src/tbox/src/tbox/coroutine/channel.c487
-rw-r--r--core/src/tbox/src/tbox/coroutine/channel.h120
-rw-r--r--core/src/tbox/src/tbox/coroutine/coroutine.c99
-rw-r--r--core/src/tbox/src/tbox/coroutine/coroutine.h120
-rw-r--r--core/src/tbox/src/tbox/coroutine/impl/coroutine.c269
-rw-r--r--core/src/tbox/src/tbox/coroutine/impl/coroutine.h179
-rw-r--r--core/src/tbox/src/tbox/coroutine/impl/impl.h37
-rw-r--r--core/src/tbox/src/tbox/coroutine/impl/prefix.h39
-rw-r--r--core/src/tbox/src/tbox/coroutine/impl/scheduler.c383
-rw-r--r--core/src/tbox/src/tbox/coroutine/impl/scheduler.h177
-rw-r--r--core/src/tbox/src/tbox/coroutine/impl/scheduler_io.c461
-rw-r--r--core/src/tbox/src/tbox/coroutine/impl/scheduler_io.h125
-rw-r--r--core/src/tbox/src/tbox/coroutine/impl/stackless/coroutine.h139
-rw-r--r--core/src/tbox/src/tbox/coroutine/impl/stackless/prefix.h36
-rw-r--r--core/src/tbox/src/tbox/coroutine/impl/stackless/scheduler.h122
-rw-r--r--core/src/tbox/src/tbox/coroutine/impl/stackless/scheduler_io.c483
-rw-r--r--core/src/tbox/src/tbox/coroutine/impl/stackless/scheduler_io.h125
-rw-r--r--core/src/tbox/src/tbox/coroutine/impl/stackless/stackless.h35
-rw-r--r--core/src/tbox/src/tbox/coroutine/lock.c66
-rw-r--r--core/src/tbox/src/tbox/coroutine/lock.h87
-rw-r--r--core/src/tbox/src/tbox/coroutine/prefix.h34
-rw-r--r--core/src/tbox/src/tbox/coroutine/scheduler.c220
-rw-r--r--core/src/tbox/src/tbox/coroutine/scheduler.h87
-rw-r--r--core/src/tbox/src/tbox/coroutine/semaphore.c176
-rw-r--r--core/src/tbox/src/tbox/coroutine/semaphore.h95
-rw-r--r--core/src/tbox/src/tbox/coroutine/stackless/core.h171
-rw-r--r--core/src/tbox/src/tbox/coroutine/stackless/coroutine.c197
-rw-r--r--core/src/tbox/src/tbox/coroutine/stackless/coroutine.h413
-rw-r--r--core/src/tbox/src/tbox/coroutine/stackless/lock.h81
-rw-r--r--core/src/tbox/src/tbox/coroutine/stackless/prefix.h57
-rw-r--r--core/src/tbox/src/tbox/coroutine/stackless/scheduler.c414
-rw-r--r--core/src/tbox/src/tbox/coroutine/stackless/scheduler.h81
-rw-r--r--core/src/tbox/src/tbox/coroutine/stackless/semaphore.h104
-rw-r--r--core/src/tbox/src/tbox/coroutine/stackless/stackless.h38
-rw-r--r--core/src/tbox/src/tbox/database/database.h36
-rw-r--r--core/src/tbox/src/tbox/database/impl/mysql.c1705
-rw-r--r--core/src/tbox/src/tbox/database/impl/mysql.h62
-rw-r--r--core/src/tbox/src/tbox/database/impl/prefix.h97
-rw-r--r--core/src/tbox/src/tbox/database/impl/sqlite3.c935
-rw-r--r--core/src/tbox/src/tbox/database/impl/sqlite3.h62
-rw-r--r--core/src/tbox/src/tbox/database/prefix.h38
-rw-r--r--core/src/tbox/src/tbox/database/sql.c414
-rw-r--r--core/src/tbox/src/tbox/database/sql.h339
-rw-r--r--core/src/tbox/src/tbox/database/value.c496
-rw-r--r--core/src/tbox/src/tbox/database/value.h463
-rw-r--r--core/src/tbox/src/tbox/object/array.c266
-rw-r--r--core/src/tbox/src/tbox/object/array.h130
-rw-r--r--core/src/tbox/src/tbox/object/boolean.c133
-rw-r--r--core/src/tbox/src/tbox/object/boolean.h78
-rw-r--r--core/src/tbox/src/tbox/object/data.c258
-rw-r--r--core/src/tbox/src/tbox/object/data.h117
-rw-r--r--core/src/tbox/src/tbox/object/date.c172
-rw-r--r--core/src/tbox/src/tbox/object/date.h88
-rw-r--r--core/src/tbox/src/tbox/object/deprecated/array.h49
-rw-r--r--core/src/tbox/src/tbox/object/deprecated/boolean.h45
-rw-r--r--core/src/tbox/src/tbox/object/deprecated/data.h47
-rw-r--r--core/src/tbox/src/tbox/object/deprecated/date.h47
-rw-r--r--core/src/tbox/src/tbox/object/deprecated/deprecated.h41
-rw-r--r--core/src/tbox/src/tbox/object/deprecated/dictionary.h68
-rw-r--r--core/src/tbox/src/tbox/object/deprecated/null.h42
-rw-r--r--core/src/tbox/src/tbox/object/deprecated/number.h100
-rw-r--r--core/src/tbox/src/tbox/object/deprecated/prefix.h35
-rw-r--r--core/src/tbox/src/tbox/object/deprecated/string.h45
-rw-r--r--core/src/tbox/src/tbox/object/dictionary.c259
-rw-r--r--core/src/tbox/src/tbox/object/dictionary.h163
-rw-r--r--core/src/tbox/src/tbox/object/impl/impl.h36
-rw-r--r--core/src/tbox/src/tbox/object/impl/object.c86
-rw-r--r--core/src/tbox/src/tbox/object/impl/object.h58
-rw-r--r--core/src/tbox/src/tbox/object/impl/prefix.h77
-rw-r--r--core/src/tbox/src/tbox/object/impl/reader/bin.c550
-rw-r--r--core/src/tbox/src/tbox/object/impl/reader/bin.h90
-rw-r--r--core/src/tbox/src/tbox/object/impl/reader/bplist.c821
-rw-r--r--core/src/tbox/src/tbox/object/impl/reader/bplist.h87
-rw-r--r--core/src/tbox/src/tbox/object/impl/reader/json.c607
-rw-r--r--core/src/tbox/src/tbox/object/impl/reader/json.h87
-rw-r--r--core/src/tbox/src/tbox/object/impl/reader/prefix.h88
-rw-r--r--core/src/tbox/src/tbox/object/impl/reader/reader.c111
-rw-r--r--core/src/tbox/src/tbox/object/impl/reader/reader.h83
-rw-r--r--core/src/tbox/src/tbox/object/impl/reader/xml.c647
-rw-r--r--core/src/tbox/src/tbox/object/impl/reader/xml.h87
-rw-r--r--core/src/tbox/src/tbox/object/impl/reader/xplist.c653
-rw-r--r--core/src/tbox/src/tbox/object/impl/reader/xplist.h87
-rw-r--r--core/src/tbox/src/tbox/object/impl/writer/bin.c429
-rw-r--r--core/src/tbox/src/tbox/object/impl/writer/bin.h102
-rw-r--r--core/src/tbox/src/tbox/object/impl/writer/bplist.c806
-rw-r--r--core/src/tbox/src/tbox/object/impl/writer/bplist.h87
-rw-r--r--core/src/tbox/src/tbox/object/impl/writer/json.c331
-rw-r--r--core/src/tbox/src/tbox/object/impl/writer/json.h90
-rw-r--r--core/src/tbox/src/tbox/object/impl/writer/prefix.h114
-rw-r--r--core/src/tbox/src/tbox/object/impl/writer/writer.c94
-rw-r--r--core/src/tbox/src/tbox/object/impl/writer/writer.h86
-rw-r--r--core/src/tbox/src/tbox/object/impl/writer/xml.c432
-rw-r--r--core/src/tbox/src/tbox/object/impl/writer/xml.h90
-rw-r--r--core/src/tbox/src/tbox/object/impl/writer/xplist.c425
-rw-r--r--core/src/tbox/src/tbox/object/impl/writer/xplist.h90
-rw-r--r--core/src/tbox/src/tbox/object/null.c70
-rw-r--r--core/src/tbox/src/tbox/object/null.h55
-rw-r--r--core/src/tbox/src/tbox/object/number.c683
-rw-r--r--core/src/tbox/src/tbox/object/number.h334
-rw-r--r--core/src/tbox/src/tbox/object/object.c405
-rw-r--r--core/src/tbox/src/tbox/object/object.h258
-rw-r--r--core/src/tbox/src/tbox/object/prefix.h104
-rw-r--r--core/src/tbox/src/tbox/object/string.c232
-rw-r--r--core/src/tbox/src/tbox/object/string.h90
-rw-r--r--core/src/tbox/src/tbox/regex/impl/impl.h48
-rw-r--r--core/src/tbox/src/tbox/regex/impl/pcre.c357
-rw-r--r--core/src/tbox/src/tbox/regex/impl/pcre2.c351
-rw-r--r--core/src/tbox/src/tbox/regex/impl/prefix.h38
-rw-r--r--core/src/tbox/src/tbox/regex/prefix.h37
-rw-r--r--core/src/tbox/src/tbox/regex/regex.c205
-rw-r--r--core/src/tbox/src/tbox/regex/regex.h422
-rw-r--r--core/src/tbox/src/tbox/tbox.c1
-rw-r--r--core/src/tbox/src/tbox/tbox.h6
-rw-r--r--core/src/tbox/src/tbox/xml/node.c466
-rw-r--r--core/src/tbox/src/tbox/xml/node.h333
-rw-r--r--core/src/tbox/src/tbox/xml/prefix.h41
-rw-r--r--core/src/tbox/src/tbox/xml/reader.c928
-rw-r--r--core/src/tbox/src/tbox/xml/reader.h298
-rw-r--r--core/src/tbox/src/tbox/xml/writer.c497
-rw-r--r--core/src/tbox/src/tbox/xml/writer.h198
-rw-r--r--core/src/tbox/src/tbox/xml/xml.h37
170 files changed, 0 insertions, 47174 deletions
diff --git a/core/src/luajit/dynasm/dasm_arm.h b/core/src/luajit/dynasm/dasm_arm.h
deleted file mode 100644
index 57e0116f5..000000000
--- a/core/src/luajit/dynasm/dasm_arm.h
+++ /dev/null
@@ -1,456 +0,0 @@
-/*
-** DynASM ARM encoding engine.
-** Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-** Released under the MIT license. See dynasm.lua for full copyright notice.
-*/
-
-#include <stddef.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdlib.h>
-
-#define DASM_ARCH "arm"
-
-#ifndef DASM_EXTERN
-#define DASM_EXTERN(a,b,c,d) 0
-#endif
-
-/* Action definitions. */
-enum {
- DASM_STOP, DASM_SECTION, DASM_ESC, DASM_REL_EXT,
- /* The following actions need a buffer position. */
- DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,
- /* The following actions also have an argument. */
- DASM_REL_PC, DASM_LABEL_PC,
- DASM_IMM, DASM_IMM12, DASM_IMM16, DASM_IMML8, DASM_IMML12, DASM_IMMV8,
- DASM__MAX
-};
-
-/* Maximum number of section buffer positions for a single dasm_put() call. */
-#define DASM_MAXSECPOS 25
-
-/* DynASM encoder status codes. Action list offset or number are or'ed in. */
-#define DASM_S_OK 0x00000000
-#define DASM_S_NOMEM 0x01000000
-#define DASM_S_PHASE 0x02000000
-#define DASM_S_MATCH_SEC 0x03000000
-#define DASM_S_RANGE_I 0x11000000
-#define DASM_S_RANGE_SEC 0x12000000
-#define DASM_S_RANGE_LG 0x13000000
-#define DASM_S_RANGE_PC 0x14000000
-#define DASM_S_RANGE_REL 0x15000000
-#define DASM_S_UNDEF_LG 0x21000000
-#define DASM_S_UNDEF_PC 0x22000000
-
-/* Macros to convert positions (8 bit section + 24 bit index). */
-#define DASM_POS2IDX(pos) ((pos)&0x00ffffff)
-#define DASM_POS2BIAS(pos) ((pos)&0xff000000)
-#define DASM_SEC2POS(sec) ((sec)<<24)
-#define DASM_POS2SEC(pos) ((pos)>>24)
-#define DASM_POS2PTR(D, pos) (D->sections[DASM_POS2SEC(pos)].rbuf + (pos))
-
-/* Action list type. */
-typedef const unsigned int *dasm_ActList;
-
-/* Per-section structure. */
-typedef struct dasm_Section {
- int *rbuf; /* Biased buffer pointer (negative section bias). */
- int *buf; /* True buffer pointer. */
- size_t bsize; /* Buffer size in bytes. */
- int pos; /* Biased buffer position. */
- int epos; /* End of biased buffer position - max single put. */
- int ofs; /* Byte offset into section. */
-} dasm_Section;
-
-/* Core structure holding the DynASM encoding state. */
-struct dasm_State {
- size_t psize; /* Allocated size of this structure. */
- dasm_ActList actionlist; /* Current actionlist pointer. */
- int *lglabels; /* Local/global chain/pos ptrs. */
- size_t lgsize;
- int *pclabels; /* PC label chains/pos ptrs. */
- size_t pcsize;
- void **globals; /* Array of globals (bias -10). */
- dasm_Section *section; /* Pointer to active section. */
- size_t codesize; /* Total size of all code sections. */
- int maxsection; /* 0 <= sectionidx < maxsection. */
- int status; /* Status code. */
- dasm_Section sections[1]; /* All sections. Alloc-extended. */
-};
-
-/* The size of the core structure depends on the max. number of sections. */
-#define DASM_PSZ(ms) (sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))
-
-
-/* Initialize DynASM state. */
-void dasm_init(Dst_DECL, int maxsection)
-{
- dasm_State *D;
- size_t psz = 0;
- int i;
- Dst_REF = NULL;
- DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
- D = Dst_REF;
- D->psize = psz;
- D->lglabels = NULL;
- D->lgsize = 0;
- D->pclabels = NULL;
- D->pcsize = 0;
- D->globals = NULL;
- D->maxsection = maxsection;
- for (i = 0; i < maxsection; i++) {
- D->sections[i].buf = NULL; /* Need this for pass3. */
- D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);
- D->sections[i].bsize = 0;
- D->sections[i].epos = 0; /* Wrong, but is recalculated after resize. */
- }
-}
-
-/* Free DynASM state. */
-void dasm_free(Dst_DECL)
-{
- dasm_State *D = Dst_REF;
- int i;
- for (i = 0; i < D->maxsection; i++)
- if (D->sections[i].buf)
- DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);
- if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);
- if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);
- DASM_M_FREE(Dst, D, D->psize);
-}
-
-/* Setup global label array. Must be called before dasm_setup(). */
-void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
-{
- dasm_State *D = Dst_REF;
- D->globals = gl - 10; /* Negative bias to compensate for locals. */
- DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
-}
-
-/* Grow PC label array. Can be called after dasm_setup(), too. */
-void dasm_growpc(Dst_DECL, unsigned int maxpc)
-{
- dasm_State *D = Dst_REF;
- size_t osz = D->pcsize;
- DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));
- memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);
-}
-
-/* Setup encoder. */
-void dasm_setup(Dst_DECL, const void *actionlist)
-{
- dasm_State *D = Dst_REF;
- int i;
- D->actionlist = (dasm_ActList)actionlist;
- D->status = DASM_S_OK;
- D->section = &D->sections[0];
- memset((void *)D->lglabels, 0, D->lgsize);
- if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
- for (i = 0; i < D->maxsection; i++) {
- D->sections[i].pos = DASM_SEC2POS(i);
- D->sections[i].ofs = 0;
- }
-}
-
-
-#ifdef DASM_CHECKS
-#define CK(x, st) \
- do { if (!(x)) { \
- D->status = DASM_S_##st|(p-D->actionlist-1); return; } } while (0)
-#define CKPL(kind, st) \
- do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \
- D->status = DASM_S_RANGE_##st|(p-D->actionlist-1); return; } } while (0)
-#else
-#define CK(x, st) ((void)0)
-#define CKPL(kind, st) ((void)0)
-#endif
-
-static int dasm_imm12(unsigned int n)
-{
- int i;
- for (i = 0; i < 16; i++, n = (n << 2) | (n >> 30))
- if (n <= 255) return (int)(n + (i << 8));
- return -1;
-}
-
-/* Pass 1: Store actions and args, link branches/labels, estimate offsets. */
-void dasm_put(Dst_DECL, int start, ...)
-{
- va_list ap;
- dasm_State *D = Dst_REF;
- dasm_ActList p = D->actionlist + start;
- dasm_Section *sec = D->section;
- int pos = sec->pos, ofs = sec->ofs;
- int *b;
-
- if (pos >= sec->epos) {
- DASM_M_GROW(Dst, int, sec->buf, sec->bsize,
- sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));
- sec->rbuf = sec->buf - DASM_POS2BIAS(pos);
- sec->epos = (int)sec->bsize/sizeof(int) - DASM_MAXSECPOS+DASM_POS2BIAS(pos);
- }
-
- b = sec->rbuf;
- b[pos++] = start;
-
- va_start(ap, start);
- while (1) {
- unsigned int ins = *p++;
- unsigned int action = (ins >> 16);
- if (action >= DASM__MAX) {
- ofs += 4;
- } else {
- int *pl, n = action >= DASM_REL_PC ? va_arg(ap, int) : 0;
- switch (action) {
- case DASM_STOP: goto stop;
- case DASM_SECTION:
- n = (ins & 255); CK(n < D->maxsection, RANGE_SEC);
- D->section = &D->sections[n]; goto stop;
- case DASM_ESC: p++; ofs += 4; break;
- case DASM_REL_EXT: break;
- case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break;
- case DASM_REL_LG:
- n = (ins & 2047) - 10; pl = D->lglabels + n;
- /* Bkwd rel or global. */
- if (n >= 0) { CK(n>=10||*pl<0, RANGE_LG); CKPL(lg, LG); goto putrel; }
- pl += 10; n = *pl;
- if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
- goto linkrel;
- case DASM_REL_PC:
- pl = D->pclabels + n; CKPL(pc, PC);
- putrel:
- n = *pl;
- if (n < 0) { /* Label exists. Get label pos and store it. */
- b[pos] = -n;
- } else {
- linkrel:
- b[pos] = n; /* Else link to rel chain, anchored at label. */
- *pl = pos;
- }
- pos++;
- break;
- case DASM_LABEL_LG:
- pl = D->lglabels + (ins & 2047) - 10; CKPL(lg, LG); goto putlabel;
- case DASM_LABEL_PC:
- pl = D->pclabels + n; CKPL(pc, PC);
- putlabel:
- n = *pl; /* n > 0: Collapse rel chain and replace with label pos. */
- while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos;
- }
- *pl = -pos; /* Label exists now. */
- b[pos++] = ofs; /* Store pass1 offset estimate. */
- break;
- case DASM_IMM:
- case DASM_IMM16:
-#ifdef DASM_CHECKS
- CK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I);
- if ((ins & 0x8000))
- CK(((n + (1<<(((ins>>5)&31)-1)))>>((ins>>5)&31)) == 0, RANGE_I);
- else
- CK((n>>((ins>>5)&31)) == 0, RANGE_I);
-#endif
- b[pos++] = n;
- break;
- case DASM_IMMV8:
- CK((n & 3) == 0, RANGE_I);
- n >>= 2;
- case DASM_IMML8:
- case DASM_IMML12:
- CK(n >= 0 ? ((n>>((ins>>5)&31)) == 0) :
- (((-n)>>((ins>>5)&31)) == 0), RANGE_I);
- b[pos++] = n;
- break;
- case DASM_IMM12:
- CK(dasm_imm12((unsigned int)n) != -1, RANGE_I);
- b[pos++] = n;
- break;
- }
- }
- }
-stop:
- va_end(ap);
- sec->pos = pos;
- sec->ofs = ofs;
-}
-#undef CK
-
-/* Pass 2: Link sections, shrink aligns, fix label offsets. */
-int dasm_link(Dst_DECL, size_t *szp)
-{
- dasm_State *D = Dst_REF;
- int secnum;
- int ofs = 0;
-
-#ifdef DASM_CHECKS
- *szp = 0;
- if (D->status != DASM_S_OK) return D->status;
- {
- int pc;
- for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)
- if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;
- }
-#endif
-
- { /* Handle globals not defined in this translation unit. */
- int idx;
- for (idx = 20; idx*sizeof(int) < D->lgsize; idx++) {
- int n = D->lglabels[idx];
- /* Undefined label: Collapse rel chain and replace with marker (< 0). */
- while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
- }
- }
-
- /* Combine all code sections. No support for data sections (yet). */
- for (secnum = 0; secnum < D->maxsection; secnum++) {
- dasm_Section *sec = D->sections + secnum;
- int *b = sec->rbuf;
- int pos = DASM_SEC2POS(secnum);
- int lastpos = sec->pos;
-
- while (pos != lastpos) {
- dasm_ActList p = D->actionlist + b[pos++];
- while (1) {
- unsigned int ins = *p++;
- unsigned int action = (ins >> 16);
- switch (action) {
- case DASM_STOP: case DASM_SECTION: goto stop;
- case DASM_ESC: p++; break;
- case DASM_REL_EXT: break;
- case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;
- case DASM_REL_LG: case DASM_REL_PC: pos++; break;
- case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
- case DASM_IMM: case DASM_IMM12: case DASM_IMM16:
- case DASM_IMML8: case DASM_IMML12: case DASM_IMMV8: pos++; break;
- }
- }
- stop: (void)0;
- }
- ofs += sec->ofs; /* Next section starts right after current section. */
- }
-
- D->codesize = ofs; /* Total size of all code sections */
- *szp = ofs;
- return DASM_S_OK;
-}
-
-#ifdef DASM_CHECKS
-#define CK(x, st) \
- do { if (!(x)) return DASM_S_##st|(p-D->actionlist-1); } while (0)
-#else
-#define CK(x, st) ((void)0)
-#endif
-
-/* Pass 3: Encode sections. */
-int dasm_encode(Dst_DECL, void *buffer)
-{
- dasm_State *D = Dst_REF;
- char *base = (char *)buffer;
- unsigned int *cp = (unsigned int *)buffer;
- int secnum;
-
- /* Encode all code sections. No support for data sections (yet). */
- for (secnum = 0; secnum < D->maxsection; secnum++) {
- dasm_Section *sec = D->sections + secnum;
- int *b = sec->buf;
- int *endb = sec->rbuf + sec->pos;
-
- while (b != endb) {
- dasm_ActList p = D->actionlist + *b++;
- while (1) {
- unsigned int ins = *p++;
- unsigned int action = (ins >> 16);
- int n = (action >= DASM_ALIGN && action < DASM__MAX) ? *b++ : 0;
- switch (action) {
- case DASM_STOP: case DASM_SECTION: goto stop;
- case DASM_ESC: *cp++ = *p++; break;
- case DASM_REL_EXT:
- n = DASM_EXTERN(Dst, (unsigned char *)cp, (ins&2047), !(ins&2048));
- goto patchrel;
- case DASM_ALIGN:
- ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0xe1a00000;
- break;
- case DASM_REL_LG:
- CK(n >= 0, UNDEF_LG);
- case DASM_REL_PC:
- CK(n >= 0, UNDEF_PC);
- n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base) - 4;
- patchrel:
- if ((ins & 0x800) == 0) {
- CK((n & 3) == 0 && ((n+0x02000000) >> 26) == 0, RANGE_REL);
- cp[-1] |= ((n >> 2) & 0x00ffffff);
- } else if ((ins & 0x1000)) {
- CK((n & 3) == 0 && -256 <= n && n <= 256, RANGE_REL);
- goto patchimml8;
- } else if ((ins & 0x2000) == 0) {
- CK((n & 3) == 0 && -4096 <= n && n <= 4096, RANGE_REL);
- goto patchimml;
- } else {
- CK((n & 3) == 0 && -1020 <= n && n <= 1020, RANGE_REL);
- n >>= 2;
- goto patchimml;
- }
- break;
- case DASM_LABEL_LG:
- ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);
- break;
- case DASM_LABEL_PC: break;
- case DASM_IMM:
- cp[-1] |= ((n>>((ins>>10)&31)) & ((1<<((ins>>5)&31))-1)) << (ins&31);
- break;
- case DASM_IMM12:
- cp[-1] |= dasm_imm12((unsigned int)n);
- break;
- case DASM_IMM16:
- cp[-1] |= ((n & 0xf000) << 4) | (n & 0x0fff);
- break;
- case DASM_IMML8: patchimml8:
- cp[-1] |= n >= 0 ? (0x00800000 | (n & 0x0f) | ((n & 0xf0) << 4)) :
- ((-n & 0x0f) | ((-n & 0xf0) << 4));
- break;
- case DASM_IMML12: case DASM_IMMV8: patchimml:
- cp[-1] |= n >= 0 ? (0x00800000 | n) : (-n);
- break;
- default: *cp++ = ins; break;
- }
- }
- stop: (void)0;
- }
- }
-
- if (base + D->codesize != (char *)cp) /* Check for phase errors. */
- return DASM_S_PHASE;
- return DASM_S_OK;
-}
-#undef CK
-
-/* Get PC label offset. */
-int dasm_getpclabel(Dst_DECL, unsigned int pc)
-{
- dasm_State *D = Dst_REF;
- if (pc*sizeof(int) < D->pcsize) {
- int pos = D->pclabels[pc];
- if (pos < 0) return *DASM_POS2PTR(D, -pos);
- if (pos > 0) return -1; /* Undefined. */
- }
- return -2; /* Unused or out of range. */
-}
-
-#ifdef DASM_CHECKS
-/* Optional sanity checker to call between isolated encoding steps. */
-int dasm_checkstep(Dst_DECL, int secmatch)
-{
- dasm_State *D = Dst_REF;
- if (D->status == DASM_S_OK) {
- int i;
- for (i = 1; i <= 9; i++) {
- if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_LG|i; break; }
- D->lglabels[i] = 0;
- }
- }
- if (D->status == DASM_S_OK && secmatch >= 0 &&
- D->section != &D->sections[secmatch])
- D->status = DASM_S_MATCH_SEC|(D->section-D->sections);
- return D->status;
-}
-#endif
-
diff --git a/core/src/luajit/dynasm/dasm_arm.lua b/core/src/luajit/dynasm/dasm_arm.lua
deleted file mode 100644
index 90a259c5c..000000000
--- a/core/src/luajit/dynasm/dasm_arm.lua
+++ /dev/null
@@ -1,1125 +0,0 @@
-------------------------------------------------------------------------------
--- DynASM ARM module.
---
--- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
--- See dynasm.lua for full copyright notice.
-------------------------------------------------------------------------------
-
--- Module information:
-local _info = {
- arch = "arm",
- description = "DynASM ARM module",
- version = "1.3.0",
- vernum = 10300,
- release = "2011-05-05",
- author = "Mike Pall",
- license = "MIT",
-}
-
--- Exported glue functions for the arch-specific module.
-local _M = { _info = _info }
-
--- Cache library functions.
-local type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs
-local assert, setmetatable, rawget = assert, setmetatable, rawget
-local _s = string
-local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
-local match, gmatch, gsub = _s.match, _s.gmatch, _s.gsub
-local concat, sort, insert = table.concat, table.sort, table.insert
-local bit = bit or require("bit")
-local band, shl, shr, sar = bit.band, bit.lshift, bit.rshift, bit.arshift
-local ror, tohex = bit.ror, bit.tohex
-
--- Inherited tables and callbacks.
-local g_opt, g_arch
-local wline, werror, wfatal, wwarn
-
--- Action name list.
--- CHECK: Keep this in sync with the C code!
-local action_names = {
- "STOP", "SECTION", "ESC", "REL_EXT",
- "ALIGN", "REL_LG", "LABEL_LG",
- "REL_PC", "LABEL_PC", "IMM", "IMM12", "IMM16", "IMML8", "IMML12", "IMMV8",
-}
-
--- Maximum number of section buffer positions for dasm_put().
--- CHECK: Keep this in sync with the C code!
-local maxsecpos = 25 -- Keep this low, to avoid excessively long C lines.
-
--- Action name -> action number.
-local map_action = {}
-for n,name in ipairs(action_names) do
- map_action[name] = n-1
-end
-
--- Action list buffer.
-local actlist = {}
-
--- Argument list for next dasm_put(). Start with offset 0 into action list.
-local actargs = { 0 }
-
--- Current number of section buffer positions for dasm_put().
-local secpos = 1
-
-------------------------------------------------------------------------------
-
--- Dump action names and numbers.
-local function dumpactions(out)
- out:write("DynASM encoding engine action codes:\n")
- for n,name in ipairs(action_names) do
- local num = map_action[name]
- out:write(format(" %-10s %02X %d\n", name, num, num))
- end
- out:write("\n")
-end
-
--- Write action list buffer as a huge static C array.
-local function writeactions(out, name)
- local nn = #actlist
- if nn == 0 then nn = 1; actlist[0] = map_action.STOP end
- out:write("static const unsigned int ", name, "[", nn, "] = {\n")
- for i = 1,nn-1 do
- assert(out:write("0x", tohex(actlist[i]), ",\n"))
- end
- assert(out:write("0x", tohex(actlist[nn]), "\n};\n\n"))
-end
-
-------------------------------------------------------------------------------
-
--- Add word to action list.
-local function wputxw(n)
- assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, "word out of range")
- actlist[#actlist+1] = n
-end
-
--- Add action to list with optional arg. Advance buffer pos, too.
-local function waction(action, val, a, num)
- local w = assert(map_action[action], "bad action name `"..action.."'")
- wputxw(w * 0x10000 + (val or 0))
- if a then actargs[#actargs+1] = a end
- if a or num then secpos = secpos + (num or 1) end
-end
-
--- Flush action list (intervening C code or buffer pos overflow).
-local function wflush(term)
- if #actlist == actargs[1] then return end -- Nothing to flush.
- if not term then waction("STOP") end -- Terminate action list.
- wline(format("dasm_put(Dst, %s);", concat(actargs, ", ")), true)
- actargs = { #actlist } -- Actionlist offset is 1st arg to next dasm_put().
- secpos = 1 -- The actionlist offset occupies a buffer position, too.
-end
-
--- Put escaped word.
-local function wputw(n)
- if n <= 0x000fffff then waction("ESC") end
- wputxw(n)
-end
-
--- Reserve position for word.
-local function wpos()
- local pos = #actlist+1
- actlist[pos] = ""
- return pos
-end
-
--- Store word to reserved position.
-local function wputpos(pos, n)
- assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, "word out of range")
- if n <= 0x000fffff then
- insert(actlist, pos+1, n)
- n = map_action.ESC * 0x10000
- end
- actlist[pos] = n
-end
-
-------------------------------------------------------------------------------
-
--- Global label name -> global label number. With auto assignment on 1st use.
-local next_global = 20
-local map_global = setmetatable({}, { __index = function(t, name)
- if not match(name, "^[%a_][%w_]*$") then werror("bad global label") end
- local n = next_global
- if n > 2047 then werror("too many global labels") end
- next_global = n + 1
- t[name] = n
- return n
-end})
-
--- Dump global labels.
-local function dumpglobals(out, lvl)
- local t = {}
- for name, n in pairs(map_global) do t[n] = name end
- out:write("Global labels:\n")
- for i=20,next_global-1 do
- out:write(format(" %s\n", t[i]))
- end
- out:write("\n")
-end
-
--- Write global label enum.
-local function writeglobals(out, prefix)
- local t = {}
- for name, n in pairs(map_global) do t[n] = name end
- out:write("enum {\n")
- for i=20,next_global-1 do
- out:write(" ", prefix, t[i], ",\n")
- end
- out:write(" ", prefix, "_MAX\n};\n")
-end
-
--- Write global label names.
-local function writeglobalnames(out, name)
- local t = {}
- for name, n in pairs(map_global) do t[n] = name end
- out:write("static const char *const ", name, "[] = {\n")
- for i=20,next_global-1 do
- out:write(" \"", t[i], "\",\n")
- end
- out:write(" (const char *)0\n};\n")
-end
-
-------------------------------------------------------------------------------
-
--- Extern label name -> extern label number. With auto assignment on 1st use.
-local next_extern = 0
-local map_extern_ = {}
-local map_extern = setmetatable({}, { __index = function(t, name)
- -- No restrictions on the name for now.
- local n = next_extern
- if n > 2047 then werror("too many extern labels") end
- next_extern = n + 1
- t[name] = n
- map_extern_[n] = name
- return n
-end})
-
--- Dump extern labels.
-local function dumpexterns(out, lvl)
- out:write("Extern labels:\n")
- for i=0,next_extern-1 do
- out:write(format(" %s\n", map_extern_[i]))
- end
- out:write("\n")
-end
-
--- Write extern label names.
-local function writeexternnames(out, name)
- out:write("static const char *const ", name, "[] = {\n")
- for i=0,next_extern-1 do
- out:write(" \"", map_extern_[i], "\",\n")
- end
- out:write(" (const char *)0\n};\n")
-end
-
-------------------------------------------------------------------------------
-
--- Arch-specific maps.
-
--- Ext. register name -> int. name.
-local map_archdef = { sp = "r13", lr = "r14", pc = "r15", }
-
--- Int. register name -> ext. name.
-local map_reg_rev = { r13 = "sp", r14 = "lr", r15 = "pc", }
-
-local map_type = {} -- Type name -> { ctype, reg }
-local ctypenum = 0 -- Type number (for Dt... macros).
-
--- Reverse defines for registers.
-function _M.revdef(s)
- return map_reg_rev[s] or s
-end
-
-local map_shift = { lsl = 0, lsr = 1, asr = 2, ror = 3, }
-
-local map_cond = {
- eq = 0, ne = 1, cs = 2, cc = 3, mi = 4, pl = 5, vs = 6, vc = 7,
- hi = 8, ls = 9, ge = 10, lt = 11, gt = 12, le = 13, al = 14,
- hs = 2, lo = 3,
-}
-
-------------------------------------------------------------------------------
-
--- Template strings for ARM instructions.
-local map_op = {
- -- Basic data processing instructions.
- and_3 = "e0000000DNPs",
- eor_3 = "e0200000DNPs",
- sub_3 = "e0400000DNPs",
- rsb_3 = "e0600000DNPs",
- add_3 = "e0800000DNPs",
- adc_3 = "e0a00000DNPs",
- sbc_3 = "e0c00000DNPs",
- rsc_3 = "e0e00000DNPs",
- tst_2 = "e1100000NP",
- teq_2 = "e1300000NP",
- cmp_2 = "e1500000NP",
- cmn_2 = "e1700000NP",
- orr_3 = "e1800000DNPs",
- mov_2 = "e1a00000DPs",
- bic_3 = "e1c00000DNPs",
- mvn_2 = "e1e00000DPs",
-
- and_4 = "e0000000DNMps",
- eor_4 = "e0200000DNMps",
- sub_4 = "e0400000DNMps",
- rsb_4 = "e0600000DNMps",
- add_4 = "e0800000DNMps",
- adc_4 = "e0a00000DNMps",
- sbc_4 = "e0c00000DNMps",
- rsc_4 = "e0e00000DNMps",
- tst_3 = "e1100000NMp",
- teq_3 = "e1300000NMp",
- cmp_3 = "e1500000NMp",
- cmn_3 = "e1700000NMp",
- orr_4 = "e1800000DNMps",
- mov_3 = "e1a00000DMps",
- bic_4 = "e1c00000DNMps",
- mvn_3 = "e1e00000DMps",
-
- lsl_3 = "e1a00000DMws",
- lsr_3 = "e1a00020DMws",
- asr_3 = "e1a00040DMws",
- ror_3 = "e1a00060DMws",
- rrx_2 = "e1a00060DMs",
-
- -- Multiply and multiply-accumulate.
- mul_3 = "e0000090NMSs",
- mla_4 = "e0200090NMSDs",
- umaal_4 = "e0400090DNMSs", -- v6
- mls_4 = "e0600090DNMSs", -- v6T2
- umull_4 = "e0800090DNMSs",
- umlal_4 = "e0a00090DNMSs",
- smull_4 = "e0c00090DNMSs",
- smlal_4 = "e0e00090DNMSs",
-
- -- Halfword multiply and multiply-accumulate.
- smlabb_4 = "e1000080NMSD", -- v5TE
- smlatb_4 = "e10000a0NMSD", -- v5TE
- smlabt_4 = "e10000c0NMSD", -- v5TE
- smlatt_4 = "e10000e0NMSD", -- v5TE
- smlawb_4 = "e1200080NMSD", -- v5TE
- smulwb_3 = "e12000a0NMS", -- v5TE
- smlawt_4 = "e12000c0NMSD", -- v5TE
- smulwt_3 = "e12000e0NMS", -- v5TE
- smlalbb_4 = "e1400080NMSD", -- v5TE
- smlaltb_4 = "e14000a0NMSD", -- v5TE
- smlalbt_4 = "e14000c0NMSD", -- v5TE
- smlaltt_4 = "e14000e0NMSD", -- v5TE
- smulbb_3 = "e1600080NMS", -- v5TE
- smultb_3 = "e16000a0NMS", -- v5TE
- smulbt_3 = "e16000c0NMS", -- v5TE
- smultt_3 = "e16000e0NMS", -- v5TE
-
- -- Miscellaneous data processing instructions.
- clz_2 = "e16f0f10DM", -- v5T
- rev_2 = "e6bf0f30DM", -- v6
- rev16_2 = "e6bf0fb0DM", -- v6
- revsh_2 = "e6ff0fb0DM", -- v6
- sel_3 = "e6800fb0DNM", -- v6
- usad8_3 = "e780f010NMS", -- v6
- usada8_4 = "e7800010NMSD", -- v6
- rbit_2 = "e6ff0f30DM", -- v6T2
- movw_2 = "e3000000DW", -- v6T2
- movt_2 = "e3400000DW", -- v6T2
- -- Note: the X encodes width-1, not width.
- sbfx_4 = "e7a00050DMvX", -- v6T2
- ubfx_4 = "e7e00050DMvX", -- v6T2
- -- Note: the X encodes the msb field, not the width.
- bfc_3 = "e7c0001fDvX", -- v6T2
- bfi_4 = "e7c00010DMvX", -- v6T2
-
- -- Packing and unpacking instructions.
- pkhbt_3 = "e6800010DNM", pkhbt_4 = "e6800010DNMv", -- v6
- pkhtb_3 = "e6800050DNM", pkhtb_4 = "e6800050DNMv", -- v6
- sxtab_3 = "e6a00070DNM", sxtab_4 = "e6a00070DNMv", -- v6
- sxtab16_3 = "e6800070DNM", sxtab16_4 = "e6800070DNMv", -- v6
- sxtah_3 = "e6b00070DNM", sxtah_4 = "e6b00070DNMv", -- v6
- sxtb_2 = "e6af0070DM", sxtb_3 = "e6af0070DMv", -- v6
- sxtb16_2 = "e68f0070DM", sxtb16_3 = "e68f0070DMv", -- v6
- sxth_2 = "e6bf0070DM", sxth_3 = "e6bf0070DMv", -- v6
- uxtab_3 = "e6e00070DNM", uxtab_4 = "e6e00070DNMv", -- v6
- uxtab16_3 = "e6c00070DNM", uxtab16_4 = "e6c00070DNMv", -- v6
- uxtah_3 = "e6f00070DNM", uxtah_4 = "e6f00070DNMv", -- v6
- uxtb_2 = "e6ef0070DM", uxtb_3 = "e6ef0070DMv", -- v6
- uxtb16_2 = "e6cf0070DM", uxtb16_3 = "e6cf0070DMv", -- v6
- uxth_2 = "e6ff0070DM", uxth_3 = "e6ff0070DMv", -- v6
-
- -- Saturating instructions.
- qadd_3 = "e1000050DMN", -- v5TE
- qsub_3 = "e1200050DMN", -- v5TE
- qdadd_3 = "e1400050DMN", -- v5TE
- qdsub_3 = "e1600050DMN", -- v5TE
- -- Note: the X for ssat* encodes sat_imm-1, not sat_imm.
- ssat_3 = "e6a00010DXM", ssat_4 = "e6a00010DXMp", -- v6
- usat_3 = "e6e00010DXM", usat_4 = "e6e00010DXMp", -- v6
- ssat16_3 = "e6a00f30DXM", -- v6
- usat16_3 = "e6e00f30DXM", -- v6
-
- -- Parallel addition and subtraction.
- sadd16_3 = "e6100f10DNM", -- v6
- sasx_3 = "e6100f30DNM", -- v6
- ssax_3 = "e6100f50DNM", -- v6
- ssub16_3 = "e6100f70DNM", -- v6
- sadd8_3 = "e6100f90DNM", -- v6
- ssub8_3 = "e6100ff0DNM", -- v6
- qadd16_3 = "e6200f10DNM", -- v6
- qasx_3 = "e6200f30DNM", -- v6
- qsax_3 = "e6200f50DNM", -- v6
- qsub16_3 = "e6200f70DNM", -- v6
- qadd8_3 = "e6200f90DNM", -- v6
- qsub8_3 = "e6200ff0DNM", -- v6
- shadd16_3 = "e6300f10DNM", -- v6
- shasx_3 = "e6300f30DNM", -- v6
- shsax_3 = "e6300f50DNM", -- v6
- shsub16_3 = "e6300f70DNM", -- v6
- shadd8_3 = "e6300f90DNM", -- v6
- shsub8_3 = "e6300ff0DNM", -- v6
- uadd16_3 = "e6500f10DNM", -- v6
- uasx_3 = "e6500f30DNM", -- v6
- usax_3 = "e6500f50DNM", -- v6
- usub16_3 = "e6500f70DNM", -- v6
- uadd8_3 = "e6500f90DNM", -- v6
- usub8_3 = "e6500ff0DNM", -- v6
- uqadd16_3 = "e6600f10DNM", -- v6
- uqasx_3 = "e6600f30DNM", -- v6
- uqsax_3 = "e6600f50DNM", -- v6
- uqsub16_3 = "e6600f70DNM", -- v6
- uqadd8_3 = "e6600f90DNM", -- v6
- uqsub8_3 = "e6600ff0DNM", -- v6
- uhadd16_3 = "e6700f10DNM", -- v6
- uhasx_3 = "e6700f30DNM", -- v6
- uhsax_3 = "e6700f50DNM", -- v6
- uhsub16_3 = "e6700f70DNM", -- v6
- uhadd8_3 = "e6700f90DNM", -- v6
- uhsub8_3 = "e6700ff0DNM", -- v6
-
- -- Load/store instructions.
- str_2 = "e4000000DL", str_3 = "e4000000DL", str_4 = "e4000000DL",
- strb_2 = "e4400000DL", strb_3 = "e4400000DL", strb_4 = "e4400000DL",
- ldr_2 = "e4100000DL", ldr_3 = "e4100000DL", ldr_4 = "e4100000DL",
- ldrb_2 = "e4500000DL", ldrb_3 = "e4500000DL", ldrb_4 = "e4500000DL",
- strh_2 = "e00000b0DL", strh_3 = "e00000b0DL",
- ldrh_2 = "e01000b0DL", ldrh_3 = "e01000b0DL",
- ldrd_2 = "e00000d0DL", ldrd_3 = "e00000d0DL", -- v5TE
- ldrsb_2 = "e01000d0DL", ldrsb_3 = "e01000d0DL",
- strd_2 = "e00000f0DL", strd_3 = "e00000f0DL", -- v5TE
- ldrsh_2 = "e01000f0DL", ldrsh_3 = "e01000f0DL",
-
- ldm_2 = "e8900000oR", ldmia_2 = "e8900000oR", ldmfd_2 = "e8900000oR",
- ldmda_2 = "e8100000oR", ldmfa_2 = "e8100000oR",
- ldmdb_2 = "e9100000oR", ldmea_2 = "e9100000oR",
- ldmib_2 = "e9900000oR", ldmed_2 = "e9900000oR",
- stm_2 = "e8800000oR", stmia_2 = "e8800000oR", stmfd_2 = "e8800000oR",
- stmda_2 = "e8000000oR", stmfa_2 = "e8000000oR",
- stmdb_2 = "e9000000oR", stmea_2 = "e9000000oR",
- stmib_2 = "e9800000oR", stmed_2 = "e9800000oR",
- pop_1 = "e8bd0000R", push_1 = "e92d0000R",
-
- -- Branch instructions.
- b_1 = "ea000000B",
- bl_1 = "eb000000B",
- blx_1 = "e12fff30C",
- bx_1 = "e12fff10M",
-
- -- Miscellaneous instructions.
- nop_0 = "e1a00000",
- mrs_1 = "e10f0000D",
- bkpt_1 = "e1200070K", -- v5T
- svc_1 = "ef000000T", swi_1 = "ef000000T",
- ud_0 = "e7f001f0",
-
- -- VFP instructions.
- ["vadd.f32_3"] = "ee300a00dnm",
- ["vadd.f64_3"] = "ee300b00Gdnm",
- ["vsub.f32_3"] = "ee300a40dnm",
- ["vsub.f64_3"] = "ee300b40Gdnm",
- ["vmul.f32_3"] = "ee200a00dnm",
- ["vmul.f64_3"] = "ee200b00Gdnm",
- ["vnmul.f32_3"] = "ee200a40dnm",
- ["vnmul.f64_3"] = "ee200b40Gdnm",
- ["vmla.f32_3"] = "ee000a00dnm",
- ["vmla.f64_3"] = "ee000b00Gdnm",
- ["vmls.f32_3"] = "ee000a40dnm",
- ["vmls.f64_3"] = "ee000b40Gdnm",
- ["vnmla.f32_3"] = "ee100a40dnm",
- ["vnmla.f64_3"] = "ee100b40Gdnm",
- ["vnmls.f32_3"] = "ee100a00dnm",
- ["vnmls.f64_3"] = "ee100b00Gdnm",
- ["vdiv.f32_3"] = "ee800a00dnm",
- ["vdiv.f64_3"] = "ee800b00Gdnm",
-
- ["vabs.f32_2"] = "eeb00ac0dm",
- ["vabs.f64_2"] = "eeb00bc0Gdm",
- ["vneg.f32_2"] = "eeb10a40dm",
- ["vneg.f64_2"] = "eeb10b40Gdm",
- ["vsqrt.f32_2"] = "eeb10ac0dm",
- ["vsqrt.f64_2"] = "eeb10bc0Gdm",
- ["vcmp.f32_2"] = "eeb40a40dm",
- ["vcmp.f64_2"] = "eeb40b40Gdm",
- ["vcmpe.f32_2"] = "eeb40ac0dm",
- ["vcmpe.f64_2"] = "eeb40bc0Gdm",
- ["vcmpz.f32_1"] = "eeb50a40d",
- ["vcmpz.f64_1"] = "eeb50b40Gd",
- ["vcmpze.f32_1"] = "eeb50ac0d",
- ["vcmpze.f64_1"] = "eeb50bc0Gd",
-
- vldr_2 = "ed100a00dl|ed100b00Gdl",
- vstr_2 = "ed000a00dl|ed000b00Gdl",
- vldm_2 = "ec900a00or",
- vldmia_2 = "ec900a00or",
- vldmdb_2 = "ed100a00or",
- vpop_1 = "ecbd0a00r",
- vstm_2 = "ec800a00or",
- vstmia_2 = "ec800a00or",
- vstmdb_2 = "ed000a00or",
- vpush_1 = "ed2d0a00r",
-
- ["vmov.f32_2"] = "eeb00a40dm|eeb00a00dY", -- #imm is VFPv3 only
- ["vmov.f64_2"] = "eeb00b40Gdm|eeb00b00GdY", -- #imm is VFPv3 only
- vmov_2 = "ee100a10Dn|ee000a10nD",
- vmov_3 = "ec500a10DNm|ec400a10mDN|ec500b10GDNm|ec400b10GmDN",
-
- vmrs_0 = "eef1fa10",
- vmrs_1 = "eef10a10D",
- vmsr_1 = "eee10a10D",
-
- ["vcvt.s32.f32_2"] = "eebd0ac0dm",
- ["vcvt.s32.f64_2"] = "eebd0bc0dGm",
- ["vcvt.u32.f32_2"] = "eebc0ac0dm",
- ["vcvt.u32.f64_2"] = "eebc0bc0dGm",
- ["vcvtr.s32.f32_2"] = "eebd0a40dm",
- ["vcvtr.s32.f64_2"] = "eebd0b40dGm",
- ["vcvtr.u32.f32_2"] = "eebc0a40dm",
- ["vcvtr.u32.f64_2"] = "eebc0b40dGm",
- ["vcvt.f32.s32_2"] = "eeb80ac0dm",
- ["vcvt.f64.s32_2"] = "eeb80bc0GdFm",
- ["vcvt.f32.u32_2"] = "eeb80a40dm",
- ["vcvt.f64.u32_2"] = "eeb80b40GdFm",
- ["vcvt.f32.f64_2"] = "eeb70bc0dGm",
- ["vcvt.f64.f32_2"] = "eeb70ac0GdFm",
-
- -- VFPv4 only:
- ["vfma.f32_3"] = "eea00a00dnm",
- ["vfma.f64_3"] = "eea00b00Gdnm",
- ["vfms.f32_3"] = "eea00a40dnm",
- ["vfms.f64_3"] = "eea00b40Gdnm",
- ["vfnma.f32_3"] = "ee900a40dnm",
- ["vfnma.f64_3"] = "ee900b40Gdnm",
- ["vfnms.f32_3"] = "ee900a00dnm",
- ["vfnms.f64_3"] = "ee900b00Gdnm",
-
- -- NYI: Advanced SIMD instructions.
-
- -- NYI: I have no need for these instructions right now:
- -- swp, swpb, strex, ldrex, strexd, ldrexd, strexb, ldrexb, strexh, ldrexh
- -- msr, nopv6, yield, wfe, wfi, sev, dbg, bxj, smc, srs, rfe
- -- cps, setend, pli, pld, pldw, clrex, dsb, dmb, isb
- -- stc, ldc, mcr, mcr2, mrc, mrc2, mcrr, mcrr2, mrrc, mrrc2, cdp, cdp2
-}
-
--- Add mnemonics for "s" variants.
-do
- local t = {}
- for k,v in pairs(map_op) do
- if sub(v, -1) == "s" then
- local v2 = sub(v, 1, 2)..char(byte(v, 3)+1)..sub(v, 4, -2)
- t[sub(k, 1, -3).."s"..sub(k, -2)] = v2
- end
- end
- for k,v in pairs(t) do
- map_op[k] = v
- end
-end
-
-------------------------------------------------------------------------------
-
-local function parse_gpr(expr)
- local tname, ovreg = match(expr, "^([%w_]+):(r1?[0-9])$")
- local tp = map_type[tname or expr]
- if tp then
- local reg = ovreg or tp.reg
- if not reg then
- werror("type `"..(tname or expr).."' needs a register override")
- end
- expr = reg
- end
- local r = match(expr, "^r(1?[0-9])$")
- if r then
- r = tonumber(r)
- if r <= 15 then return r, tp end
- end
- werror("bad register name `"..expr.."'")
-end
-
-local function parse_gpr_pm(expr)
- local pm, expr2 = match(expr, "^([+-]?)(.*)$")
- return parse_gpr(expr2), (pm == "-")
-end
-
-local function parse_vr(expr, tp)
- local t, r = match(expr, "^([sd])([0-9]+)$")
- if t == tp then
- r = tonumber(r)
- if r <= 31 then
- if t == "s" then return shr(r, 1), band(r, 1) end
- return band(r, 15), shr(r, 4)
- end
- end
- werror("bad register name `"..expr.."'")
-end
-
-local function parse_reglist(reglist)
- reglist = match(reglist, "^{%s*([^}]*)}$")
- if not reglist then werror("register list expected") end
- local rr = 0
- for p in gmatch(reglist..",", "%s*([^,]*),") do
- local rbit = shl(1, parse_gpr(gsub(p, "%s+$", "")))
- if band(rr, rbit) ~= 0 then
- werror("duplicate register `"..p.."'")
- end
- rr = rr + rbit
- end
- return rr
-end
-
-local function parse_vrlist(reglist)
- local ta, ra, tb, rb = match(reglist,
- "^{%s*([sd])([0-9]+)%s*%-%s*([sd])([0-9]+)%s*}$")
- ra, rb = tonumber(ra), tonumber(rb)
- if ta and ta == tb and ra and rb and ra <= 31 and rb <= 31 and ra <= rb then
- local nr = rb+1 - ra
- if ta == "s" then
- return shl(shr(ra,1),12)+shl(band(ra,1),22) + nr
- else
- return shl(band(ra,15),12)+shl(shr(ra,4),22) + nr*2 + 0x100
- end
- end
- werror("register list expected")
-end
-
-local function parse_imm(imm, bits, shift, scale, signed)
- imm = match(imm, "^#(.*)$")
- if not imm then werror("expected immediate operand") end
- local n = tonumber(imm)
- if n then
- local m = sar(n, scale)
- if shl(m, scale) == n then
- if signed then
- local s = sar(m, bits-1)
- if s == 0 then return shl(m, shift)
- elseif s == -1 then return shl(m + shl(1, bits), shift) end
- else
- if sar(m, bits) == 0 then return shl(m, shift) end
- end
- end
- werror("out of range immediate `"..imm.."'")
- else
- waction("IMM", (signed and 32768 or 0)+scale*1024+bits*32+shift, imm)
- return 0
- end
-end
-
-local function parse_imm12(imm)
- local n = tonumber(imm)
- if n then
- local m = band(n)
- for i=0,-15,-1 do
- if shr(m, 8) == 0 then return m + shl(band(i, 15), 8) end
- m = ror(m, 2)
- end
- werror("out of range immediate `"..imm.."'")
- else
- waction("IMM12", 0, imm)
- return 0
- end
-end
-
-local function parse_imm16(imm)
- imm = match(imm, "^#(.*)$")
- if not imm then werror("expected immediate operand") end
- local n = tonumber(imm)
- if n then
- if shr(n, 16) == 0 then return band(n, 0x0fff) + shl(band(n, 0xf000), 4) end
- werror("out of range immediate `"..imm.."'")
- else
- waction("IMM16", 32*16, imm)
- return 0
- end
-end
-
-local function parse_imm_load(imm, ext)
- local n = tonumber(imm)
- if n then
- if ext then
- if n >= -255 and n <= 255 then
- local up = 0x00800000
- if n < 0 then n = -n; up = 0 end
- return shl(band(n, 0xf0), 4) + band(n, 0x0f) + up
- end
- else
- if n >= -4095 and n <= 4095 then
- if n >= 0 then return n+0x00800000 end
- return -n
- end
- end
- werror("out of range immediate `"..imm.."'")
- else
- waction(ext and "IMML8" or "IMML12", 32768 + shl(ext and 8 or 12, 5), imm)
- return 0
- end
-end
-
-local function parse_shift(shift, gprok)
- if shift == "rrx" then
- return 3 * 32
- else
- local s, s2 = match(shift, "^(%S+)%s*(.*)$")
- s = map_shift[s]
- if not s then werror("expected shift operand") end
- if sub(s2, 1, 1) == "#" then
- return parse_imm(s2, 5, 7, 0, false) + shl(s, 5)
- else
- if not gprok then werror("expected immediate shift operand") end
- return shl(parse_gpr(s2), 8) + shl(s, 5) + 16
- end
- end
-end
-
-local function parse_label(label, def)
- local prefix = sub(label, 1, 2)
- -- =>label (pc label reference)
- if prefix == "=>" then
- return "PC", 0, sub(label, 3)
- end
- -- ->name (global label reference)
- if prefix == "->" then
- return "LG", map_global[sub(label, 3)]
- end
- if def then
- -- [1-9] (local label definition)
- if match(label, "^[1-9]$") then
- return "LG", 10+tonumber(label)
- end
- else
- -- [<>][1-9] (local label reference)
- local dir, lnum = match(label, "^([<>])([1-9])$")
- if dir then -- Fwd: 1-9, Bkwd: 11-19.
- return "LG", lnum + (dir == ">" and 0 or 10)
- end
- -- extern label (extern label reference)
- local extname = match(label, "^extern%s+(%S+)$")
- if extname then
- return "EXT", map_extern[extname]
- end
- end
- werror("bad label `"..label.."'")
-end
-
-local function parse_load(params, nparams, n, op)
- local oplo = band(op, 255)
- local ext, ldrd = (oplo ~= 0), (oplo == 208)
- local d
- if (ldrd or oplo == 240) then
- d = band(shr(op, 12), 15)
- if band(d, 1) ~= 0 then werror("odd destination register") end
- end
- local pn = params[n]
- local p1, wb = match(pn, "^%[%s*(.-)%s*%](!?)$")
- local p2 = params[n+1]
- if not p1 then
- if not p2 then
- if match(pn, "^[<>=%-]") or match(pn, "^extern%s+") then
- local mode, n, s = parse_label(pn, false)
- waction("REL_"..mode, n + (ext and 0x1800 or 0x0800), s, 1)
- return op + 15 * 65536 + 0x01000000 + (ext and 0x00400000 or 0)
- end
- local reg, tailr = match(pn, "^([%w_:]+)%s*(.*)$")
- if reg and tailr ~= "" then
- local d, tp = parse_gpr(reg)
- if tp then
- waction(ext and "IMML8" or "IMML12", 32768 + 32*(ext and 8 or 12),
- format(tp.ctypefmt, tailr))
- return op + shl(d, 16) + 0x01000000 + (ext and 0x00400000 or 0)
- end
- end
- end
- werror("expected address operand")
- end
- if wb == "!" then op = op + 0x00200000 end
- if p2 then
- if wb == "!" then werror("bad use of '!'") end
- local p3 = params[n+2]
- op = op + shl(parse_gpr(p1), 16)
- local imm = match(p2, "^#(.*)$")
- if imm then
- local m = parse_imm_load(imm, ext)
- if p3 then werror("too many parameters") end
- op = op + m + (ext and 0x00400000 or 0)
- else
- local m, neg = parse_gpr_pm(p2)
- if ldrd and (m == d or m-1 == d) then werror("register conflict") end
- op = op + m + (neg and 0 or 0x00800000) + (ext and 0 or 0x02000000)
- if p3 then op = op + parse_shift(p3) end
- end
- else
- local p1a, p2 = match(p1, "^([^,%s]*)%s*(.*)$")
- op = op + shl(parse_gpr(p1a), 16) + 0x01000000
- if p2 ~= "" then
- local imm = match(p2, "^,%s*#(.*)$")
- if imm then
- local m = parse_imm_load(imm, ext)
- op = op + m + (ext and 0x00400000 or 0)
- else
- local p2a, p3 = match(p2, "^,%s*([^,%s]*)%s*,?%s*(.*)$")
- local m, neg = parse_gpr_pm(p2a)
- if ldrd and (m == d or m-1 == d) then werror("register conflict") end
- op = op + m + (neg and 0 or 0x00800000) + (ext and 0 or 0x02000000)
- if p3 ~= "" then
- if ext then werror("too many parameters") end
- op = op + parse_shift(p3)
- end
- end
- else
- if wb == "!" then werror("bad use of '!'") end
- op = op + (ext and 0x00c00000 or 0x00800000)
- end
- end
- return op
-end
-
-local function parse_vload(q)
- local reg, imm = match(q, "^%[%s*([^,%s]*)%s*(.*)%]$")
- if reg then
- local d = shl(parse_gpr(reg), 16)
- if imm == "" then return d end
- imm = match(imm, "^,%s*#(.*)$")
- if imm then
- local n = tonumber(imm)
- if n then
- if n >= -1020 and n <= 1020 and n%4 == 0 then
- return d + (n >= 0 and n/4+0x00800000 or -n/4)
- end
- werror("out of range immediate `"..imm.."'")
- else
- waction("IMMV8", 32768 + 32*8, imm)
- return d
- end
- end
- else
- if match(q, "^[<>=%-]") or match(q, "^extern%s+") then
- local mode, n, s = parse_label(q, false)
- waction("REL_"..mode, n + 0x2800, s, 1)
- return 15 * 65536
- end
- local reg, tailr = match(q, "^([%w_:]+)%s*(.*)$")
- if reg and tailr ~= "" then
- local d, tp = parse_gpr(reg)
- if tp then
- waction("IMMV8", 32768 + 32*8, format(tp.ctypefmt, tailr))
- return shl(d, 16)
- end
- end
- end
- werror("expected address operand")
-end
-
-------------------------------------------------------------------------------
-
--- Handle opcodes defined with template strings.
-local function parse_template(params, template, nparams, pos)
- local op = tonumber(sub(template, 1, 8), 16)
- local n = 1
- local vr = "s"
-
- -- Process each character.
- for p in gmatch(sub(template, 9), ".") do
- local q = params[n]
- if p == "D" then
- op = op + shl(parse_gpr(q), 12); n = n + 1
- elseif p == "N" then
- op = op + shl(parse_gpr(q), 16); n = n + 1
- elseif p == "S" then
- op = op + shl(parse_gpr(q), 8); n = n + 1
- elseif p == "M" then
- op = op + parse_gpr(q); n = n + 1
- elseif p == "d" then
- local r,h = parse_vr(q, vr); op = op+shl(r,12)+shl(h,22); n = n + 1
- elseif p == "n" then
- local r,h = parse_vr(q, vr); op = op+shl(r,16)+shl(h,7); n = n + 1
- elseif p == "m" then
- local r,h = parse_vr(q, vr); op = op+r+shl(h,5); n = n + 1
- elseif p == "P" then
- local imm = match(q, "^#(.*)$")
- if imm then
- op = op + parse_imm12(imm) + 0x02000000
- else
- op = op + parse_gpr(q)
- end
- n = n + 1
- elseif p == "p" then
- op = op + parse_shift(q, true); n = n + 1
- elseif p == "L" then
- op = parse_load(params, nparams, n, op)
- elseif p == "l" then
- op = op + parse_vload(q)
- elseif p == "B" then
- local mode, n, s = parse_label(q, false)
- waction("REL_"..mode, n, s, 1)
- elseif p == "C" then -- blx gpr vs. blx label.
- if match(q, "^([%w_]+):(r1?[0-9])$") or match(q, "^r(1?[0-9])$") then
- op = op + parse_gpr(q)
- else
- if op < 0xe0000000 then werror("unconditional instruction") end
- local mode, n, s = parse_label(q, false)
- waction("REL_"..mode, n, s, 1)
- op = 0xfa000000
- end
- elseif p == "F" then
- vr = "s"
- elseif p == "G" then
- vr = "d"
- elseif p == "o" then
- local r, wb = match(q, "^([^!]*)(!?)$")
- op = op + shl(parse_gpr(r), 16) + (wb == "!" and 0x00200000 or 0)
- n = n + 1
- elseif p == "R" then
- op = op + parse_reglist(q); n = n + 1
- elseif p == "r" then
- op = op + parse_vrlist(q); n = n + 1
- elseif p == "W" then
- op = op + parse_imm16(q); n = n + 1
- elseif p == "v" then
- op = op + parse_imm(q, 5, 7, 0, false); n = n + 1
- elseif p == "w" then
- local imm = match(q, "^#(.*)$")
- if imm then
- op = op + parse_imm(q, 5, 7, 0, false); n = n + 1
- else
- op = op + shl(parse_gpr(q), 8) + 16
- end
- elseif p == "X" then
- op = op + parse_imm(q, 5, 16, 0, false); n = n + 1
- elseif p == "Y" then
- local imm = tonumber(match(q, "^#(.*)$")); n = n + 1
- if not imm or shr(imm, 8) ~= 0 then
- werror("bad immediate operand")
- end
- op = op + shl(band(imm, 0xf0), 12) + band(imm, 0x0f)
- elseif p == "K" then
- local imm = tonumber(match(q, "^#(.*)$")); n = n + 1
- if not imm or shr(imm, 16) ~= 0 then
- werror("bad immediate operand")
- end
- op = op + shl(band(imm, 0xfff0), 4) + band(imm, 0x000f)
- elseif p == "T" then
- op = op + parse_imm(q, 24, 0, 0, false); n = n + 1
- elseif p == "s" then
- -- Ignored.
- else
- assert(false)
- end
- end
- wputpos(pos, op)
-end
-
-map_op[".template__"] = function(params, template, nparams)
- if not params then return template:gsub("%x%x%x%x%x%x%x%x", "") end
-
- -- Limit number of section buffer positions used by a single dasm_put().
- -- A single opcode needs a maximum of 3 positions.
- if secpos+3 > maxsecpos then wflush() end
- local pos = wpos()
- local lpos, apos, spos = #actlist, #actargs, secpos
-
- local ok, err
- for t in gmatch(template, "[^|]+") do
- ok, err = pcall(parse_template, params, t, nparams, pos)
- if ok then return end
- secpos = spos
- actlist[lpos+1] = nil
- actlist[lpos+2] = nil
- actlist[lpos+3] = nil
- actargs[apos+1] = nil
- actargs[apos+2] = nil
- actargs[apos+3] = nil
- end
- error(err, 0)
-end
-
-------------------------------------------------------------------------------
-
--- Pseudo-opcode to mark the position where the action list is to be emitted.
-map_op[".actionlist_1"] = function(params)
- if not params then return "cvar" end
- local name = params[1] -- No syntax check. You get to keep the pieces.
- wline(function(out) writeactions(out, name) end)
-end
-
--- Pseudo-opcode to mark the position where the global enum is to be emitted.
-map_op[".globals_1"] = function(params)
- if not params then return "prefix" end
- local prefix = params[1] -- No syntax check. You get to keep the pieces.
- wline(function(out) writeglobals(out, prefix) end)
-end
-
--- Pseudo-opcode to mark the position where the global names are to be emitted.
-map_op[".globalnames_1"] = function(params)
- if not params then return "cvar" end
- local name = params[1] -- No syntax check. You get to keep the pieces.
- wline(function(out) writeglobalnames(out, name) end)
-end
-
--- Pseudo-opcode to mark the position where the extern names are to be emitted.
-map_op[".externnames_1"] = function(params)
- if not params then return "cvar" end
- local name = params[1] -- No syntax check. You get to keep the pieces.
- wline(function(out) writeexternnames(out, name) end)
-end
-
-------------------------------------------------------------------------------
-
--- Label pseudo-opcode (converted from trailing colon form).
-map_op[".label_1"] = function(params)
- if not params then return "[1-9] | ->global | =>pcexpr" end
- if secpos+1 > maxsecpos then wflush() end
- local mode, n, s = parse_label(params[1], true)
- if mode == "EXT" then werror("bad label definition") end
- waction("LABEL_"..mode, n, s, 1)
-end
-
-------------------------------------------------------------------------------
-
--- Pseudo-opcodes for data storage.
-map_op[".long_*"] = function(params)
- if not params then return "imm..." end
- for _,p in ipairs(params) do
- local n = tonumber(p)
- if not n then werror("bad immediate `"..p.."'") end
- if n < 0 then n = n + 2^32 end
- wputw(n)
- if secpos+2 > maxsecpos then wflush() end
- end
-end
-
--- Alignment pseudo-opcode.
-map_op[".align_1"] = function(params)
- if not params then return "numpow2" end
- if secpos+1 > maxsecpos then wflush() end
- local align = tonumber(params[1])
- if align then
- local x = align
- -- Must be a power of 2 in the range (2 ... 256).
- for i=1,8 do
- x = x / 2
- if x == 1 then
- waction("ALIGN", align-1, nil, 1) -- Action byte is 2**n-1.
- return
- end
- end
- end
- werror("bad alignment")
-end
-
-------------------------------------------------------------------------------
-
--- Pseudo-opcode for (primitive) type definitions (map to C types).
-map_op[".type_3"] = function(params, nparams)
- if not params then
- return nparams == 2 and "name, ctype" or "name, ctype, reg"
- end
- local name, ctype, reg = params[1], params[2], params[3]
- if not match(name, "^[%a_][%w_]*$") then
- werror("bad type name `"..name.."'")
- end
- local tp = map_type[name]
- if tp then
- werror("duplicate type `"..name.."'")
- end
- -- Add #type to defines. A bit unclean to put it in map_archdef.
- map_archdef["#"..name] = "sizeof("..ctype..")"
- -- Add new type and emit shortcut define.
- local num = ctypenum + 1
- map_type[name] = {
- ctype = ctype,
- ctypefmt = format("Dt%X(%%s)", num),
- reg = reg,
- }
- wline(format("#define Dt%X(_V) (int)(ptrdiff_t)&(((%s *)0)_V)", num, ctype))
- ctypenum = num
-end
-map_op[".type_2"] = map_op[".type_3"]
-
--- Dump type definitions.
-local function dumptypes(out, lvl)
- local t = {}
- for name in pairs(map_type) do t[#t+1] = name end
- sort(t)
- out:write("Type definitions:\n")
- for _,name in ipairs(t) do
- local tp = map_type[name]
- local reg = tp.reg or ""
- out:write(format(" %-20s %-20s %s\n", name, tp.ctype, reg))
- end
- out:write("\n")
-end
-
-------------------------------------------------------------------------------
-
--- Set the current section.
-function _M.section(num)
- waction("SECTION", num)
- wflush(true) -- SECTION is a terminal action.
-end
-
-------------------------------------------------------------------------------
-
--- Dump architecture description.
-function _M.dumparch(out)
- out:write(format("DynASM %s version %s, released %s\n\n",
- _info.arch, _info.version, _info.release))
- dumpactions(out)
-end
-
--- Dump all user defined elements.
-function _M.dumpdef(out, lvl)
- dumptypes(out, lvl)
- dumpglobals(out, lvl)
- dumpexterns(out, lvl)
-end
-
-------------------------------------------------------------------------------
-
--- Pass callbacks from/to the DynASM core.
-function _M.passcb(wl, we, wf, ww)
- wline, werror, wfatal, wwarn = wl, we, wf, ww
- return wflush
-end
-
--- Setup the arch-specific module.
-function _M.setup(arch, opt)
- g_arch, g_opt = arch, opt
-end
-
--- Merge the core maps and the arch-specific maps.
-function _M.mergemaps(map_coreop, map_def)
- setmetatable(map_op, { __index = function(t, k)
- local v = map_coreop[k]
- if v then return v end
- local k1, cc, k2 = match(k, "^(.-)(..)([._].*)$")
- local cv = map_cond[cc]
- if cv then
- local v = rawget(t, k1..k2)
- if type(v) == "string" then
- local scv = format("%x", cv)
- return gsub(scv..sub(v, 2), "|e", "|"..scv)
- end
- end
- end })
- setmetatable(map_def, { __index = map_archdef })
- return map_op, map_def
-end
-
-return _M
-
-------------------------------------------------------------------------------
-
diff --git a/core/src/luajit/dynasm/dasm_mips.h b/core/src/luajit/dynasm/dasm_mips.h
deleted file mode 100644
index 2f4c2d222..000000000
--- a/core/src/luajit/dynasm/dasm_mips.h
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
-** DynASM MIPS encoding engine.
-** Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-** Released under the MIT license. See dynasm.lua for full copyright notice.
-*/
-
-#include <stddef.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdlib.h>
-
-#define DASM_ARCH "mips"
-
-#ifndef DASM_EXTERN
-#define DASM_EXTERN(a,b,c,d) 0
-#endif
-
-/* Action definitions. */
-enum {
- DASM_STOP, DASM_SECTION, DASM_ESC, DASM_REL_EXT,
- /* The following actions need a buffer position. */
- DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,
- /* The following actions also have an argument. */
- DASM_REL_PC, DASM_LABEL_PC, DASM_IMM,
- DASM__MAX
-};
-
-/* Maximum number of section buffer positions for a single dasm_put() call. */
-#define DASM_MAXSECPOS 25
-
-/* DynASM encoder status codes. Action list offset or number are or'ed in. */
-#define DASM_S_OK 0x00000000
-#define DASM_S_NOMEM 0x01000000
-#define DASM_S_PHASE 0x02000000
-#define DASM_S_MATCH_SEC 0x03000000
-#define DASM_S_RANGE_I 0x11000000
-#define DASM_S_RANGE_SEC 0x12000000
-#define DASM_S_RANGE_LG 0x13000000
-#define DASM_S_RANGE_PC 0x14000000
-#define DASM_S_RANGE_REL 0x15000000
-#define DASM_S_UNDEF_LG 0x21000000
-#define DASM_S_UNDEF_PC 0x22000000
-
-/* Macros to convert positions (8 bit section + 24 bit index). */
-#define DASM_POS2IDX(pos) ((pos)&0x00ffffff)
-#define DASM_POS2BIAS(pos) ((pos)&0xff000000)
-#define DASM_SEC2POS(sec) ((sec)<<24)
-#define DASM_POS2SEC(pos) ((pos)>>24)
-#define DASM_POS2PTR(D, pos) (D->sections[DASM_POS2SEC(pos)].rbuf + (pos))
-
-/* Action list type. */
-typedef const unsigned int *dasm_ActList;
-
-/* Per-section structure. */
-typedef struct dasm_Section {
- int *rbuf; /* Biased buffer pointer (negative section bias). */
- int *buf; /* True buffer pointer. */
- size_t bsize; /* Buffer size in bytes. */
- int pos; /* Biased buffer position. */
- int epos; /* End of biased buffer position - max single put. */
- int ofs; /* Byte offset into section. */
-} dasm_Section;
-
-/* Core structure holding the DynASM encoding state. */
-struct dasm_State {
- size_t psize; /* Allocated size of this structure. */
- dasm_ActList actionlist; /* Current actionlist pointer. */
- int *lglabels; /* Local/global chain/pos ptrs. */
- size_t lgsize;
- int *pclabels; /* PC label chains/pos ptrs. */
- size_t pcsize;
- void **globals; /* Array of globals (bias -10). */
- dasm_Section *section; /* Pointer to active section. */
- size_t codesize; /* Total size of all code sections. */
- int maxsection; /* 0 <= sectionidx < maxsection. */
- int status; /* Status code. */
- dasm_Section sections[1]; /* All sections. Alloc-extended. */
-};
-
-/* The size of the core structure depends on the max. number of sections. */
-#define DASM_PSZ(ms) (sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))
-
-
-/* Initialize DynASM state. */
-void dasm_init(Dst_DECL, int maxsection)
-{
- dasm_State *D;
- size_t psz = 0;
- int i;
- Dst_REF = NULL;
- DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
- D = Dst_REF;
- D->psize = psz;
- D->lglabels = NULL;
- D->lgsize = 0;
- D->pclabels = NULL;
- D->pcsize = 0;
- D->globals = NULL;
- D->maxsection = maxsection;
- for (i = 0; i < maxsection; i++) {
- D->sections[i].buf = NULL; /* Need this for pass3. */
- D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);
- D->sections[i].bsize = 0;
- D->sections[i].epos = 0; /* Wrong, but is recalculated after resize. */
- }
-}
-
-/* Free DynASM state. */
-void dasm_free(Dst_DECL)
-{
- dasm_State *D = Dst_REF;
- int i;
- for (i = 0; i < D->maxsection; i++)
- if (D->sections[i].buf)
- DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);
- if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);
- if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);
- DASM_M_FREE(Dst, D, D->psize);
-}
-
-/* Setup global label array. Must be called before dasm_setup(). */
-void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
-{
- dasm_State *D = Dst_REF;
- D->globals = gl - 10; /* Negative bias to compensate for locals. */
- DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
-}
-
-/* Grow PC label array. Can be called after dasm_setup(), too. */
-void dasm_growpc(Dst_DECL, unsigned int maxpc)
-{
- dasm_State *D = Dst_REF;
- size_t osz = D->pcsize;
- DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));
- memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);
-}
-
-/* Setup encoder. */
-void dasm_setup(Dst_DECL, const void *actionlist)
-{
- dasm_State *D = Dst_REF;
- int i;
- D->actionlist = (dasm_ActList)actionlist;
- D->status = DASM_S_OK;
- D->section = &D->sections[0];
- memset((void *)D->lglabels, 0, D->lgsize);
- if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
- for (i = 0; i < D->maxsection; i++) {
- D->sections[i].pos = DASM_SEC2POS(i);
- D->sections[i].ofs = 0;
- }
-}
-
-
-#ifdef DASM_CHECKS
-#define CK(x, st) \
- do { if (!(x)) { \
- D->status = DASM_S_##st|(p-D->actionlist-1); return; } } while (0)
-#define CKPL(kind, st) \
- do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \
- D->status = DASM_S_RANGE_##st|(p-D->actionlist-1); return; } } while (0)
-#else
-#define CK(x, st) ((void)0)
-#define CKPL(kind, st) ((void)0)
-#endif
-
-/* Pass 1: Store actions and args, link branches/labels, estimate offsets. */
-void dasm_put(Dst_DECL, int start, ...)
-{
- va_list ap;
- dasm_State *D = Dst_REF;
- dasm_ActList p = D->actionlist + start;
- dasm_Section *sec = D->section;
- int pos = sec->pos, ofs = sec->ofs;
- int *b;
-
- if (pos >= sec->epos) {
- DASM_M_GROW(Dst, int, sec->buf, sec->bsize,
- sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));
- sec->rbuf = sec->buf - DASM_POS2BIAS(pos);
- sec->epos = (int)sec->bsize/sizeof(int) - DASM_MAXSECPOS+DASM_POS2BIAS(pos);
- }
-
- b = sec->rbuf;
- b[pos++] = start;
-
- va_start(ap, start);
- while (1) {
- unsigned int ins = *p++;
- unsigned int action = (ins >> 16) - 0xff00;
- if (action >= DASM__MAX) {
- ofs += 4;
- } else {
- int *pl, n = action >= DASM_REL_PC ? va_arg(ap, int) : 0;
- switch (action) {
- case DASM_STOP: goto stop;
- case DASM_SECTION:
- n = (ins & 255); CK(n < D->maxsection, RANGE_SEC);
- D->section = &D->sections[n]; goto stop;
- case DASM_ESC: p++; ofs += 4; break;
- case DASM_REL_EXT: break;
- case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break;
- case DASM_REL_LG:
- n = (ins & 2047) - 10; pl = D->lglabels + n;
- /* Bkwd rel or global. */
- if (n >= 0) { CK(n>=10||*pl<0, RANGE_LG); CKPL(lg, LG); goto putrel; }
- pl += 10; n = *pl;
- if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
- goto linkrel;
- case DASM_REL_PC:
- pl = D->pclabels + n; CKPL(pc, PC);
- putrel:
- n = *pl;
- if (n < 0) { /* Label exists. Get label pos and store it. */
- b[pos] = -n;
- } else {
- linkrel:
- b[pos] = n; /* Else link to rel chain, anchored at label. */
- *pl = pos;
- }
- pos++;
- break;
- case DASM_LABEL_LG:
- pl = D->lglabels + (ins & 2047) - 10; CKPL(lg, LG); goto putlabel;
- case DASM_LABEL_PC:
- pl = D->pclabels + n; CKPL(pc, PC);
- putlabel:
- n = *pl; /* n > 0: Collapse rel chain and replace with label pos. */
- while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos;
- }
- *pl = -pos; /* Label exists now. */
- b[pos++] = ofs; /* Store pass1 offset estimate. */
- break;
- case DASM_IMM:
-#ifdef DASM_CHECKS
- CK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I);
-#endif
- n >>= ((ins>>10)&31);
-#ifdef DASM_CHECKS
- if (ins & 0x8000)
- CK(((n + (1<<(((ins>>5)&31)-1)))>>((ins>>5)&31)) == 0, RANGE_I);
- else
- CK((n>>((ins>>5)&31)) == 0, RANGE_I);
-#endif
- b[pos++] = n;
- break;
- }
- }
- }
-stop:
- va_end(ap);
- sec->pos = pos;
- sec->ofs = ofs;
-}
-#undef CK
-
-/* Pass 2: Link sections, shrink aligns, fix label offsets. */
-int dasm_link(Dst_DECL, size_t *szp)
-{
- dasm_State *D = Dst_REF;
- int secnum;
- int ofs = 0;
-
-#ifdef DASM_CHECKS
- *szp = 0;
- if (D->status != DASM_S_OK) return D->status;
- {
- int pc;
- for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)
- if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;
- }
-#endif
-
- { /* Handle globals not defined in this translation unit. */
- int idx;
- for (idx = 20; idx*sizeof(int) < D->lgsize; idx++) {
- int n = D->lglabels[idx];
- /* Undefined label: Collapse rel chain and replace with marker (< 0). */
- while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
- }
- }
-
- /* Combine all code sections. No support for data sections (yet). */
- for (secnum = 0; secnum < D->maxsection; secnum++) {
- dasm_Section *sec = D->sections + secnum;
- int *b = sec->rbuf;
- int pos = DASM_SEC2POS(secnum);
- int lastpos = sec->pos;
-
- while (pos != lastpos) {
- dasm_ActList p = D->actionlist + b[pos++];
- while (1) {
- unsigned int ins = *p++;
- unsigned int action = (ins >> 16) - 0xff00;
- switch (action) {
- case DASM_STOP: case DASM_SECTION: goto stop;
- case DASM_ESC: p++; break;
- case DASM_REL_EXT: break;
- case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;
- case DASM_REL_LG: case DASM_REL_PC: pos++; break;
- case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
- case DASM_IMM: pos++; break;
- }
- }
- stop: (void)0;
- }
- ofs += sec->ofs; /* Next section starts right after current section. */
- }
-
- D->codesize = ofs; /* Total size of all code sections */
- *szp = ofs;
- return DASM_S_OK;
-}
-
-#ifdef DASM_CHECKS
-#define CK(x, st) \
- do { if (!(x)) return DASM_S_##st|(p-D->actionlist-1); } while (0)
-#else
-#define CK(x, st) ((void)0)
-#endif
-
-/* Pass 3: Encode sections. */
-int dasm_encode(Dst_DECL, void *buffer)
-{
- dasm_State *D = Dst_REF;
- char *base = (char *)buffer;
- unsigned int *cp = (unsigned int *)buffer;
- int secnum;
-
- /* Encode all code sections. No support for data sections (yet). */
- for (secnum = 0; secnum < D->maxsection; secnum++) {
- dasm_Section *sec = D->sections + secnum;
- int *b = sec->buf;
- int *endb = sec->rbuf + sec->pos;
-
- while (b != endb) {
- dasm_ActList p = D->actionlist + *b++;
- while (1) {
- unsigned int ins = *p++;
- unsigned int action = (ins >> 16) - 0xff00;
- int n = (action >= DASM_ALIGN && action < DASM__MAX) ? *b++ : 0;
- switch (action) {
- case DASM_STOP: case DASM_SECTION: goto stop;
- case DASM_ESC: *cp++ = *p++; break;
- case DASM_REL_EXT:
- n = DASM_EXTERN(Dst, (unsigned char *)cp, (ins & 2047), 1);
- goto patchrel;
- case DASM_ALIGN:
- ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0x60000000;
- break;
- case DASM_REL_LG:
- CK(n >= 0, UNDEF_LG);
- case DASM_REL_PC:
- CK(n >= 0, UNDEF_PC);
- n = *DASM_POS2PTR(D, n);
- if (ins & 2048)
- n = n - (int)((char *)cp - base);
- else
- n = (n + (int)base) & 0x0fffffff;
- patchrel:
- CK((n & 3) == 0 &&
- ((n + ((ins & 2048) ? 0x00020000 : 0)) >>
- ((ins & 2048) ? 18 : 28)) == 0, RANGE_REL);
- cp[-1] |= ((n>>2) & ((ins & 2048) ? 0x0000ffff: 0x03ffffff));
- break;
- case DASM_LABEL_LG:
- ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);
- break;
- case DASM_LABEL_PC: break;
- case DASM_IMM:
- cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31);
- break;
- default: *cp++ = ins; break;
- }
- }
- stop: (void)0;
- }
- }
-
- if (base + D->codesize != (char *)cp) /* Check for phase errors. */
- return DASM_S_PHASE;
- return DASM_S_OK;
-}
-#undef CK
-
-/* Get PC label offset. */
-int dasm_getpclabel(Dst_DECL, unsigned int pc)
-{
- dasm_State *D = Dst_REF;
- if (pc*sizeof(int) < D->pcsize) {
- int pos = D->pclabels[pc];
- if (pos < 0) return *DASM_POS2PTR(D, -pos);
- if (pos > 0) return -1; /* Undefined. */
- }
- return -2; /* Unused or out of range. */
-}
-
-#ifdef DASM_CHECKS
-/* Optional sanity checker to call between isolated encoding steps. */
-int dasm_checkstep(Dst_DECL, int secmatch)
-{
- dasm_State *D = Dst_REF;
- if (D->status == DASM_S_OK) {
- int i;
- for (i = 1; i <= 9; i++) {
- if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_LG|i; break; }
- D->lglabels[i] = 0;
- }
- }
- if (D->status == DASM_S_OK && secmatch >= 0 &&
- D->section != &D->sections[secmatch])
- D->status = DASM_S_MATCH_SEC|(D->section-D->sections);
- return D->status;
-}
-#endif
-
diff --git a/core/src/luajit/dynasm/dasm_mips.lua b/core/src/luajit/dynasm/dasm_mips.lua
deleted file mode 100644
index ae0dbd7a9..000000000
--- a/core/src/luajit/dynasm/dasm_mips.lua
+++ /dev/null
@@ -1,953 +0,0 @@
-------------------------------------------------------------------------------
--- DynASM MIPS module.
---
--- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
--- See dynasm.lua for full copyright notice.
-------------------------------------------------------------------------------
-
--- Module information:
-local _info = {
- arch = "mips",
- description = "DynASM MIPS module",
- version = "1.3.0",
- vernum = 10300,
- release = "2012-01-23",
- author = "Mike Pall",
- license = "MIT",
-}
-
--- Exported glue functions for the arch-specific module.
-local _M = { _info = _info }
-
--- Cache library functions.
-local type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs
-local assert, setmetatable = assert, setmetatable
-local _s = string
-local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
-local match, gmatch = _s.match, _s.gmatch
-local concat, sort = table.concat, table.sort
-local bit = bit or require("bit")
-local band, shl, sar, tohex = bit.band, bit.lshift, bit.arshift, bit.tohex
-
--- Inherited tables and callbacks.
-local g_opt, g_arch
-local wline, werror, wfatal, wwarn
-
--- Action name list.
--- CHECK: Keep this in sync with the C code!
-local action_names = {
- "STOP", "SECTION", "ESC", "REL_EXT",
- "ALIGN", "REL_LG", "LABEL_LG",
- "REL_PC", "LABEL_PC", "IMM",
-}
-
--- Maximum number of section buffer positions for dasm_put().
--- CHECK: Keep this in sync with the C code!
-local maxsecpos = 25 -- Keep this low, to avoid excessively long C lines.
-
--- Action name -> action number.
-local map_action = {}
-for n,name in ipairs(action_names) do
- map_action[name] = n-1
-end
-
--- Action list buffer.
-local actlist = {}
-
--- Argument list for next dasm_put(). Start with offset 0 into action list.
-local actargs = { 0 }
-
--- Current number of section buffer positions for dasm_put().
-local secpos = 1
-
-------------------------------------------------------------------------------
-
--- Dump action names and numbers.
-local function dumpactions(out)
- out:write("DynASM encoding engine action codes:\n")
- for n,name in ipairs(action_names) do
- local num = map_action[name]
- out:write(format(" %-10s %02X %d\n", name, num, num))
- end
- out:write("\n")
-end
-
--- Write action list buffer as a huge static C array.
-local function writeactions(out, name)
- local nn = #actlist
- if nn == 0 then nn = 1; actlist[0] = map_action.STOP end
- out:write("static const unsigned int ", name, "[", nn, "] = {\n")
- for i = 1,nn-1 do
- assert(out:write("0x", tohex(actlist[i]), ",\n"))
- end
- assert(out:write("0x", tohex(actlist[nn]), "\n};\n\n"))
-end
-
-------------------------------------------------------------------------------
-
--- Add word to action list.
-local function wputxw(n)
- assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, "word out of range")
- actlist[#actlist+1] = n
-end
-
--- Add action to list with optional arg. Advance buffer pos, too.
-local function waction(action, val, a, num)
- local w = assert(map_action[action], "bad action name `"..action.."'")
- wputxw(0xff000000 + w * 0x10000 + (val or 0))
- if a then actargs[#actargs+1] = a end
- if a or num then secpos = secpos + (num or 1) end
-end
-
--- Flush action list (intervening C code or buffer pos overflow).
-local function wflush(term)
- if #actlist == actargs[1] then return end -- Nothing to flush.
- if not term then waction("STOP") end -- Terminate action list.
- wline(format("dasm_put(Dst, %s);", concat(actargs, ", ")), true)
- actargs = { #actlist } -- Actionlist offset is 1st arg to next dasm_put().
- secpos = 1 -- The actionlist offset occupies a buffer position, too.
-end
-
--- Put escaped word.
-local function wputw(n)
- if n >= 0xff000000 then waction("ESC") end
- wputxw(n)
-end
-
--- Reserve position for word.
-local function wpos()
- local pos = #actlist+1
- actlist[pos] = ""
- return pos
-end
-
--- Store word to reserved position.
-local function wputpos(pos, n)
- assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, "word out of range")
- actlist[pos] = n
-end
-
-------------------------------------------------------------------------------
-
--- Global label name -> global label number. With auto assignment on 1st use.
-local next_global = 20
-local map_global = setmetatable({}, { __index = function(t, name)
- if not match(name, "^[%a_][%w_]*$") then werror("bad global label") end
- local n = next_global
- if n > 2047 then werror("too many global labels") end
- next_global = n + 1
- t[name] = n
- return n
-end})
-
--- Dump global labels.
-local function dumpglobals(out, lvl)
- local t = {}
- for name, n in pairs(map_global) do t[n] = name end
- out:write("Global labels:\n")
- for i=20,next_global-1 do
- out:write(format(" %s\n", t[i]))
- end
- out:write("\n")
-end
-
--- Write global label enum.
-local function writeglobals(out, prefix)
- local t = {}
- for name, n in pairs(map_global) do t[n] = name end
- out:write("enum {\n")
- for i=20,next_global-1 do
- out:write(" ", prefix, t[i], ",\n")
- end
- out:write(" ", prefix, "_MAX\n};\n")
-end
-
--- Write global label names.
-local function writeglobalnames(out, name)
- local t = {}
- for name, n in pairs(map_global) do t[n] = name end
- out:write("static const char *const ", name, "[] = {\n")
- for i=20,next_global-1 do
- out:write(" \"", t[i], "\",\n")
- end
- out:write(" (const char *)0\n};\n")
-end
-
-------------------------------------------------------------------------------
-
--- Extern label name -> extern label number. With auto assignment on 1st use.
-local next_extern = 0
-local map_extern_ = {}
-local map_extern = setmetatable({}, { __index = function(t, name)
- -- No restrictions on the name for now.
- local n = next_extern
- if n > 2047 then werror("too many extern labels") end
- next_extern = n + 1
- t[name] = n
- map_extern_[n] = name
- return n
-end})
-
--- Dump extern labels.
-local function dumpexterns(out, lvl)
- out:write("Extern labels:\n")
- for i=0,next_extern-1 do
- out:write(format(" %s\n", map_extern_[i]))
- end
- out:write("\n")
-end
-
--- Write extern label names.
-local function writeexternnames(out, name)
- out:write("static const char *const ", name, "[] = {\n")
- for i=0,next_extern-1 do
- out:write(" \"", map_extern_[i], "\",\n")
- end
- out:write(" (const char *)0\n};\n")
-end
-
-------------------------------------------------------------------------------
-
--- Arch-specific maps.
-local map_archdef = { sp="r29", ra="r31" } -- Ext. register name -> int. name.
-
-local map_type = {} -- Type name -> { ctype, reg }
-local ctypenum = 0 -- Type number (for Dt... macros).
-
--- Reverse defines for registers.
-function _M.revdef(s)
- if s == "r29" then return "sp"
- elseif s == "r31" then return "ra" end
- return s
-end
-
-------------------------------------------------------------------------------
-
--- Template strings for MIPS instructions.
-local map_op = {
- -- First-level opcodes.
- j_1 = "08000000J",
- jal_1 = "0c000000J",
- b_1 = "10000000B",
- beqz_2 = "10000000SB",
- beq_3 = "10000000STB",
- bnez_2 = "14000000SB",
- bne_3 = "14000000STB",
- blez_2 = "18000000SB",
- bgtz_2 = "1c000000SB",
- addi_3 = "20000000TSI",
- li_2 = "24000000TI",
- addiu_3 = "24000000TSI",
- slti_3 = "28000000TSI",
- sltiu_3 = "2c000000TSI",
- andi_3 = "30000000TSU",
- lu_2 = "34000000TU",
- ori_3 = "34000000TSU",
- xori_3 = "38000000TSU",
- lui_2 = "3c000000TU",
- beqzl_2 = "50000000SB",
- beql_3 = "50000000STB",
- bnezl_2 = "54000000SB",
- bnel_3 = "54000000STB",
- blezl_2 = "58000000SB",
- bgtzl_2 = "5c000000SB",
- lb_2 = "80000000TO",
- lh_2 = "84000000TO",
- lwl_2 = "88000000TO",
- lw_2 = "8c000000TO",
- lbu_2 = "90000000TO",
- lhu_2 = "94000000TO",
- lwr_2 = "98000000TO",
- sb_2 = "a0000000TO",
- sh_2 = "a4000000TO",
- swl_2 = "a8000000TO",
- sw_2 = "ac000000TO",
- swr_2 = "b8000000TO",
- cache_2 = "bc000000NO",
- ll_2 = "c0000000TO",
- lwc1_2 = "c4000000HO",
- pref_2 = "cc000000NO",
- ldc1_2 = "d4000000HO",
- sc_2 = "e0000000TO",
- swc1_2 = "e4000000HO",
- sdc1_2 = "f4000000HO",
-
- -- Opcode SPECIAL.
- nop_0 = "00000000",
- sll_3 = "00000000DTA",
- movf_2 = "00000001DS",
- movf_3 = "00000001DSC",
- movt_2 = "00010001DS",
- movt_3 = "00010001DSC",
- srl_3 = "00000002DTA",
- rotr_3 = "00200002DTA",
- sra_3 = "00000003DTA",
- sllv_3 = "00000004DTS",
- srlv_3 = "00000006DTS",
- rotrv_3 = "00000046DTS",
- srav_3 = "00000007DTS",
- jr_1 = "00000008S",
- jalr_1 = "0000f809S",
- jalr_2 = "00000009DS",
- movz_3 = "0000000aDST",
- movn_3 = "0000000bDST",
- syscall_0 = "0000000c",
- syscall_1 = "0000000cY",
- break_0 = "0000000d",
- break_1 = "0000000dY",
- sync_0 = "0000000f",
- mfhi_1 = "00000010D",
- mthi_1 = "00000011S",
- mflo_1 = "00000012D",
- mtlo_1 = "00000013S",
- mult_2 = "00000018ST",
- multu_2 = "00000019ST",
- div_2 = "0000001aST",
- divu_2 = "0000001bST",
- add_3 = "00000020DST",
- move_2 = "00000021DS",
- addu_3 = "00000021DST",
- sub_3 = "00000022DST",
- negu_2 = "00000023DT",
- subu_3 = "00000023DST",
- and_3 = "00000024DST",
- or_3 = "00000025DST",
- xor_3 = "00000026DST",
- not_2 = "00000027DS",
- nor_3 = "00000027DST",
- slt_3 = "0000002aDST",
- sltu_3 = "0000002bDST",
- tge_2 = "00000030ST",
- tge_3 = "00000030STZ",
- tgeu_2 = "00000031ST",
- tgeu_3 = "00000031STZ",
- tlt_2 = "00000032ST",
- tlt_3 = "00000032STZ",
- tltu_2 = "00000033ST",
- tltu_3 = "00000033STZ",
- teq_2 = "00000034ST",
- teq_3 = "00000034STZ",
- tne_2 = "00000036ST",
- tne_3 = "00000036STZ",
-
- -- Opcode REGIMM.
- bltz_2 = "04000000SB",
- bgez_2 = "04010000SB",
- bltzl_2 = "04020000SB",
- bgezl_2 = "04030000SB",
- tgei_2 = "04080000SI",
- tgeiu_2 = "04090000SI",
- tlti_2 = "040a0000SI",
- tltiu_2 = "040b0000SI",
- teqi_2 = "040c0000SI",
- tnei_2 = "040e0000SI",
- bltzal_2 = "04100000SB",
- bal_1 = "04110000B",
- bgezal_2 = "04110000SB",
- bltzall_2 = "04120000SB",
- bgezall_2 = "04130000SB",
- synci_1 = "041f0000O",
-
- -- Opcode SPECIAL2.
- madd_2 = "70000000ST",
- maddu_2 = "70000001ST",
- mul_3 = "70000002DST",
- msub_2 = "70000004ST",
- msubu_2 = "70000005ST",
- clz_2 = "70000020DS=",
- clo_2 = "70000021DS=",
- sdbbp_0 = "7000003f",
- sdbbp_1 = "7000003fY",
-
- -- Opcode SPECIAL3.
- ext_4 = "7c000000TSAM", -- Note: last arg is msbd = size-1
- ins_4 = "7c000004TSAM", -- Note: last arg is msb = pos+size-1
- wsbh_2 = "7c0000a0DT",
- seb_2 = "7c000420DT",
- seh_2 = "7c000620DT",
- rdhwr_2 = "7c00003bTD",
-
- -- Opcode COP0.
- mfc0_2 = "40000000TD",
- mfc0_3 = "40000000TDW",
- mtc0_2 = "40800000TD",
- mtc0_3 = "40800000TDW",
- rdpgpr_2 = "41400000DT",
- di_0 = "41606000",
- di_1 = "41606000T",
- ei_0 = "41606020",
- ei_1 = "41606020T",
- wrpgpr_2 = "41c00000DT",
- tlbr_0 = "42000001",
- tlbwi_0 = "42000002",
- tlbwr_0 = "42000006",
- tlbp_0 = "42000008",
- eret_0 = "42000018",
- deret_0 = "4200001f",
- wait_0 = "42000020",
-
- -- Opcode COP1.
- mfc1_2 = "44000000TG",
- cfc1_2 = "44400000TG",
- mfhc1_2 = "44600000TG",
- mtc1_2 = "44800000TG",
- ctc1_2 = "44c00000TG",
- mthc1_2 = "44e00000TG",
-
- bc1f_1 = "45000000B",
- bc1f_2 = "45000000CB",
- bc1t_1 = "45010000B",
- bc1t_2 = "45010000CB",
- bc1fl_1 = "45020000B",
- bc1fl_2 = "45020000CB",
- bc1tl_1 = "45030000B",
- bc1tl_2 = "45030000CB",
-
- ["add.s_3"] = "46000000FGH",
- ["sub.s_3"] = "46000001FGH",
- ["mul.s_3"] = "46000002FGH",
- ["div.s_3"] = "46000003FGH",
- ["sqrt.s_2"] = "46000004FG",
- ["abs.s_2"] = "46000005FG",
- ["mov.s_2"] = "46000006FG",
- ["neg.s_2"] = "46000007FG",
- ["round.l.s_2"] = "46000008FG",
- ["trunc.l.s_2"] = "46000009FG",
- ["ceil.l.s_2"] = "4600000aFG",
- ["floor.l.s_2"] = "4600000bFG",
- ["round.w.s_2"] = "4600000cFG",
- ["trunc.w.s_2"] = "4600000dFG",
- ["ceil.w.s_2"] = "4600000eFG",
- ["floor.w.s_2"] = "4600000fFG",
- ["movf.s_2"] = "46000011FG",
- ["movf.s_3"] = "46000011FGC",
- ["movt.s_2"] = "46010011FG",
- ["movt.s_3"] = "46010011FGC",
- ["movz.s_3"] = "46000012FGT",
- ["movn.s_3"] = "46000013FGT",
- ["recip.s_2"] = "46000015FG",
- ["rsqrt.s_2"] = "46000016FG",
- ["cvt.d.s_2"] = "46000021FG",
- ["cvt.w.s_2"] = "46000024FG",
- ["cvt.l.s_2"] = "46000025FG",
- ["cvt.ps.s_3"] = "46000026FGH",
- ["c.f.s_2"] = "46000030GH",
- ["c.f.s_3"] = "46000030VGH",
- ["c.un.s_2"] = "46000031GH",
- ["c.un.s_3"] = "46000031VGH",
- ["c.eq.s_2"] = "46000032GH",
- ["c.eq.s_3"] = "46000032VGH",
- ["c.ueq.s_2"] = "46000033GH",
- ["c.ueq.s_3"] = "46000033VGH",
- ["c.olt.s_2"] = "46000034GH",
- ["c.olt.s_3"] = "46000034VGH",
- ["c.ult.s_2"] = "46000035GH",
- ["c.ult.s_3"] = "46000035VGH",
- ["c.ole.s_2"] = "46000036GH",
- ["c.ole.s_3"] = "46000036VGH",
- ["c.ule.s_2"] = "46000037GH",
- ["c.ule.s_3"] = "46000037VGH",
- ["c.sf.s_2"] = "46000038GH",
- ["c.sf.s_3"] = "46000038VGH",
- ["c.ngle.s_2"] = "46000039GH",
- ["c.ngle.s_3"] = "46000039VGH",
- ["c.seq.s_2"] = "4600003aGH",
- ["c.seq.s_3"] = "4600003aVGH",
- ["c.ngl.s_2"] = "4600003bGH",
- ["c.ngl.s_3"] = "4600003bVGH",
- ["c.lt.s_2"] = "4600003cGH",
- ["c.lt.s_3"] = "4600003cVGH",
- ["c.nge.s_2"] = "4600003dGH",
- ["c.nge.s_3"] = "4600003dVGH",
- ["c.le.s_2"] = "4600003eGH",
- ["c.le.s_3"] = "4600003eVGH",
- ["c.ngt.s_2"] = "4600003fGH",
- ["c.ngt.s_3"] = "4600003fVGH",
-
- ["add.d_3"] = "46200000FGH",
- ["sub.d_3"] = "46200001FGH",
- ["mul.d_3"] = "46200002FGH",
- ["div.d_3"] = "46200003FGH",
- ["sqrt.d_2"] = "46200004FG",
- ["abs.d_2"] = "46200005FG",
- ["mov.d_2"] = "46200006FG",
- ["neg.d_2"] = "46200007FG",
- ["round.l.d_2"] = "46200008FG",
- ["trunc.l.d_2"] = "46200009FG",
- ["ceil.l.d_2"] = "4620000aFG",
- ["floor.l.d_2"] = "4620000bFG",
- ["round.w.d_2"] = "4620000cFG",
- ["trunc.w.d_2"] = "4620000dFG",
- ["ceil.w.d_2"] = "4620000eFG",
- ["floor.w.d_2"] = "4620000fFG",
- ["movf.d_2"] = "46200011FG",
- ["movf.d_3"] = "46200011FGC",
- ["movt.d_2"] = "46210011FG",
- ["movt.d_3"] = "46210011FGC",
- ["movz.d_3"] = "46200012FGT",
- ["movn.d_3"] = "46200013FGT",
- ["recip.d_2"] = "46200015FG",
- ["rsqrt.d_2"] = "46200016FG",
- ["cvt.s.d_2"] = "46200020FG",
- ["cvt.w.d_2"] = "46200024FG",
- ["cvt.l.d_2"] = "46200025FG",
- ["c.f.d_2"] = "46200030GH",
- ["c.f.d_3"] = "46200030VGH",
- ["c.un.d_2"] = "46200031GH",
- ["c.un.d_3"] = "46200031VGH",
- ["c.eq.d_2"] = "46200032GH",
- ["c.eq.d_3"] = "46200032VGH",
- ["c.ueq.d_2"] = "46200033GH",
- ["c.ueq.d_3"] = "46200033VGH",
- ["c.olt.d_2"] = "46200034GH",
- ["c.olt.d_3"] = "46200034VGH",
- ["c.ult.d_2"] = "46200035GH",
- ["c.ult.d_3"] = "46200035VGH",
- ["c.ole.d_2"] = "46200036GH",
- ["c.ole.d_3"] = "46200036VGH",
- ["c.ule.d_2"] = "46200037GH",
- ["c.ule.d_3"] = "46200037VGH",
- ["c.sf.d_2"] = "46200038GH",
- ["c.sf.d_3"] = "46200038VGH",
- ["c.ngle.d_2"] = "46200039GH",
- ["c.ngle.d_3"] = "46200039VGH",
- ["c.seq.d_2"] = "4620003aGH",
- ["c.seq.d_3"] = "4620003aVGH",
- ["c.ngl.d_2"] = "4620003bGH",
- ["c.ngl.d_3"] = "4620003bVGH",
- ["c.lt.d_2"] = "4620003cGH",
- ["c.lt.d_3"] = "4620003cVGH",
- ["c.nge.d_2"] = "4620003dGH",
- ["c.nge.d_3"] = "4620003dVGH",
- ["c.le.d_2"] = "4620003eGH",
- ["c.le.d_3"] = "4620003eVGH",
- ["c.ngt.d_2"] = "4620003fGH",
- ["c.ngt.d_3"] = "4620003fVGH",
-
- ["add.ps_3"] = "46c00000FGH",
- ["sub.ps_3"] = "46c00001FGH",
- ["mul.ps_3"] = "46c00002FGH",
- ["abs.ps_2"] = "46c00005FG",
- ["mov.ps_2"] = "46c00006FG",
- ["neg.ps_2"] = "46c00007FG",
- ["movf.ps_2"] = "46c00011FG",
- ["movf.ps_3"] = "46c00011FGC",
- ["movt.ps_2"] = "46c10011FG",
- ["movt.ps_3"] = "46c10011FGC",
- ["movz.ps_3"] = "46c00012FGT",
- ["movn.ps_3"] = "46c00013FGT",
- ["cvt.s.pu_2"] = "46c00020FG",
- ["cvt.s.pl_2"] = "46c00028FG",
- ["pll.ps_3"] = "46c0002cFGH",
- ["plu.ps_3"] = "46c0002dFGH",
- ["pul.ps_3"] = "46c0002eFGH",
- ["puu.ps_3"] = "46c0002fFGH",
- ["c.f.ps_2"] = "46c00030GH",
- ["c.f.ps_3"] = "46c00030VGH",
- ["c.un.ps_2"] = "46c00031GH",
- ["c.un.ps_3"] = "46c00031VGH",
- ["c.eq.ps_2"] = "46c00032GH",
- ["c.eq.ps_3"] = "46c00032VGH",
- ["c.ueq.ps_2"] = "46c00033GH",
- ["c.ueq.ps_3"] = "46c00033VGH",
- ["c.olt.ps_2"] = "46c00034GH",
- ["c.olt.ps_3"] = "46c00034VGH",
- ["c.ult.ps_2"] = "46c00035GH",
- ["c.ult.ps_3"] = "46c00035VGH",
- ["c.ole.ps_2"] = "46c00036GH",
- ["c.ole.ps_3"] = "46c00036VGH",
- ["c.ule.ps_2"] = "46c00037GH",
- ["c.ule.ps_3"] = "46c00037VGH",
- ["c.sf.ps_2"] = "46c00038GH",
- ["c.sf.ps_3"] = "46c00038VGH",
- ["c.ngle.ps_2"] = "46c00039GH",
- ["c.ngle.ps_3"] = "46c00039VGH",
- ["c.seq.ps_2"] = "46c0003aGH",
- ["c.seq.ps_3"] = "46c0003aVGH",
- ["c.ngl.ps_2"] = "46c0003bGH",
- ["c.ngl.ps_3"] = "46c0003bVGH",
- ["c.lt.ps_2"] = "46c0003cGH",
- ["c.lt.ps_3"] = "46c0003cVGH",
- ["c.nge.ps_2"] = "46c0003dGH",
- ["c.nge.ps_3"] = "46c0003dVGH",
- ["c.le.ps_2"] = "46c0003eGH",
- ["c.le.ps_3"] = "46c0003eVGH",
- ["c.ngt.ps_2"] = "46c0003fGH",
- ["c.ngt.ps_3"] = "46c0003fVGH",
-
- ["cvt.s.w_2"] = "46800020FG",
- ["cvt.d.w_2"] = "46800021FG",
-
- ["cvt.s.l_2"] = "46a00020FG",
- ["cvt.d.l_2"] = "46a00021FG",
-
- -- Opcode COP1X.
- lwxc1_2 = "4c000000FX",
- ldxc1_2 = "4c000001FX",
- luxc1_2 = "4c000005FX",
- swxc1_2 = "4c000008FX",
- sdxc1_2 = "4c000009FX",
- suxc1_2 = "4c00000dFX",
- prefx_2 = "4c00000fMX",
- ["alnv.ps_4"] = "4c00001eFGHS",
- ["madd.s_4"] = "4c000020FRGH",
- ["madd.d_4"] = "4c000021FRGH",
- ["madd.ps_4"] = "4c000026FRGH",
- ["msub.s_4"] = "4c000028FRGH",
- ["msub.d_4"] = "4c000029FRGH",
- ["msub.ps_4"] = "4c00002eFRGH",
- ["nmadd.s_4"] = "4c000030FRGH",
- ["nmadd.d_4"] = "4c000031FRGH",
- ["nmadd.ps_4"] = "4c000036FRGH",
- ["nmsub.s_4"] = "4c000038FRGH",
- ["nmsub.d_4"] = "4c000039FRGH",
- ["nmsub.ps_4"] = "4c00003eFRGH",
-}
-
-------------------------------------------------------------------------------
-
-local function parse_gpr(expr)
- local tname, ovreg = match(expr, "^([%w_]+):(r[1-3]?[0-9])$")
- local tp = map_type[tname or expr]
- if tp then
- local reg = ovreg or tp.reg
- if not reg then
- werror("type `"..(tname or expr).."' needs a register override")
- end
- expr = reg
- end
- local r = match(expr, "^r([1-3]?[0-9])$")
- if r then
- r = tonumber(r)
- if r <= 31 then return r, tp end
- end
- werror("bad register name `"..expr.."'")
-end
-
-local function parse_fpr(expr)
- local r = match(expr, "^f([1-3]?[0-9])$")
- if r then
- r = tonumber(r)
- if r <= 31 then return r end
- end
- werror("bad register name `"..expr.."'")
-end
-
-local function parse_imm(imm, bits, shift, scale, signed)
- local n = tonumber(imm)
- if n then
- local m = sar(n, scale)
- if shl(m, scale) == n then
- if signed then
- local s = sar(m, bits-1)
- if s == 0 then return shl(m, shift)
- elseif s == -1 then return shl(m + shl(1, bits), shift) end
- else
- if sar(m, bits) == 0 then return shl(m, shift) end
- end
- end
- werror("out of range immediate `"..imm.."'")
- elseif match(imm, "^[rf]([1-3]?[0-9])$") or
- match(imm, "^([%w_]+):([rf][1-3]?[0-9])$") then
- werror("expected immediate operand, got register")
- else
- waction("IMM", (signed and 32768 or 0)+scale*1024+bits*32+shift, imm)
- return 0
- end
-end
-
-local function parse_disp(disp)
- local imm, reg = match(disp, "^(.*)%(([%w_:]+)%)$")
- if imm then
- local r = shl(parse_gpr(reg), 21)
- local extname = match(imm, "^extern%s+(%S+)$")
- if extname then
- waction("REL_EXT", map_extern[extname], nil, 1)
- return r
- else
- return r + parse_imm(imm, 16, 0, 0, true)
- end
- end
- local reg, tailr = match(disp, "^([%w_:]+)%s*(.*)$")
- if reg and tailr ~= "" then
- local r, tp = parse_gpr(reg)
- if tp then
- waction("IMM", 32768+16*32, format(tp.ctypefmt, tailr))
- return shl(r, 21)
- end
- end
- werror("bad displacement `"..disp.."'")
-end
-
-local function parse_index(idx)
- local rt, rs = match(idx, "^(.*)%(([%w_:]+)%)$")
- if rt then
- rt = parse_gpr(rt)
- rs = parse_gpr(rs)
- return shl(rt, 16) + shl(rs, 21)
- end
- werror("bad index `"..idx.."'")
-end
-
-local function parse_label(label, def)
- local prefix = sub(label, 1, 2)
- -- =>label (pc label reference)
- if prefix == "=>" then
- return "PC", 0, sub(label, 3)
- end
- -- ->name (global label reference)
- if prefix == "->" then
- return "LG", map_global[sub(label, 3)]
- end
- if def then
- -- [1-9] (local label definition)
- if match(label, "^[1-9]$") then
- return "LG", 10+tonumber(label)
- end
- else
- -- [<>][1-9] (local label reference)
- local dir, lnum = match(label, "^([<>])([1-9])$")
- if dir then -- Fwd: 1-9, Bkwd: 11-19.
- return "LG", lnum + (dir == ">" and 0 or 10)
- end
- -- extern label (extern label reference)
- local extname = match(label, "^extern%s+(%S+)$")
- if extname then
- return "EXT", map_extern[extname]
- end
- end
- werror("bad label `"..label.."'")
-end
-
-------------------------------------------------------------------------------
-
--- Handle opcodes defined with template strings.
-map_op[".template__"] = function(params, template, nparams)
- if not params then return sub(template, 9) end
- local op = tonumber(sub(template, 1, 8), 16)
- local n = 1
-
- -- Limit number of section buffer positions used by a single dasm_put().
- -- A single opcode needs a maximum of 2 positions (ins/ext).
- if secpos+2 > maxsecpos then wflush() end
- local pos = wpos()
-
- -- Process each character.
- for p in gmatch(sub(template, 9), ".") do
- if p == "D" then
- op = op + shl(parse_gpr(params[n]), 11); n = n + 1
- elseif p == "T" then
- op = op + shl(parse_gpr(params[n]), 16); n = n + 1
- elseif p == "S" then
- op = op + shl(parse_gpr(params[n]), 21); n = n + 1
- elseif p == "F" then
- op = op + shl(parse_fpr(params[n]), 6); n = n + 1
- elseif p == "G" then
- op = op + shl(parse_fpr(params[n]), 11); n = n + 1
- elseif p == "H" then
- op = op + shl(parse_fpr(params[n]), 16); n = n + 1
- elseif p == "R" then
- op = op + shl(parse_fpr(params[n]), 21); n = n + 1
- elseif p == "I" then
- op = op + parse_imm(params[n], 16, 0, 0, true); n = n + 1
- elseif p == "U" then
- op = op + parse_imm(params[n], 16, 0, 0, false); n = n + 1
- elseif p == "O" then
- op = op + parse_disp(params[n]); n = n + 1
- elseif p == "X" then
- op = op + parse_index(params[n]); n = n + 1
- elseif p == "B" or p == "J" then
- local mode, n, s = parse_label(params[n], false)
- if p == "B" then n = n + 2048 end
- waction("REL_"..mode, n, s, 1)
- n = n + 1
- elseif p == "A" then
- op = op + parse_imm(params[n], 5, 6, 0, false); n = n + 1
- elseif p == "M" then
- op = op + parse_imm(params[n], 5, 11, 0, false); n = n + 1
- elseif p == "N" then
- op = op + parse_imm(params[n], 5, 16, 0, false); n = n + 1
- elseif p == "C" then
- op = op + parse_imm(params[n], 3, 18, 0, false); n = n + 1
- elseif p == "V" then
- op = op + parse_imm(params[n], 3, 8, 0, false); n = n + 1
- elseif p == "W" then
- op = op + parse_imm(params[n], 3, 0, 0, false); n = n + 1
- elseif p == "Y" then
- op = op + parse_imm(params[n], 20, 6, 0, false); n = n + 1
- elseif p == "Z" then
- op = op + parse_imm(params[n], 10, 6, 0, false); n = n + 1
- elseif p == "=" then
- op = op + shl(band(op, 0xf800), 5) -- Copy D to T for clz, clo.
- else
- assert(false)
- end
- end
- wputpos(pos, op)
-end
-
-------------------------------------------------------------------------------
-
--- Pseudo-opcode to mark the position where the action list is to be emitted.
-map_op[".actionlist_1"] = function(params)
- if not params then return "cvar" end
- local name = params[1] -- No syntax check. You get to keep the pieces.
- wline(function(out) writeactions(out, name) end)
-end
-
--- Pseudo-opcode to mark the position where the global enum is to be emitted.
-map_op[".globals_1"] = function(params)
- if not params then return "prefix" end
- local prefix = params[1] -- No syntax check. You get to keep the pieces.
- wline(function(out) writeglobals(out, prefix) end)
-end
-
--- Pseudo-opcode to mark the position where the global names are to be emitted.
-map_op[".globalnames_1"] = function(params)
- if not params then return "cvar" end
- local name = params[1] -- No syntax check. You get to keep the pieces.
- wline(function(out) writeglobalnames(out, name) end)
-end
-
--- Pseudo-opcode to mark the position where the extern names are to be emitted.
-map_op[".externnames_1"] = function(params)
- if not params then return "cvar" end
- local name = params[1] -- No syntax check. You get to keep the pieces.
- wline(function(out) writeexternnames(out, name) end)
-end
-
-------------------------------------------------------------------------------
-
--- Label pseudo-opcode (converted from trailing colon form).
-map_op[".label_1"] = function(params)
- if not params then return "[1-9] | ->global | =>pcexpr" end
- if secpos+1 > maxsecpos then wflush() end
- local mode, n, s = parse_label(params[1], true)
- if mode == "EXT" then werror("bad label definition") end
- waction("LABEL_"..mode, n, s, 1)
-end
-
-------------------------------------------------------------------------------
-
--- Pseudo-opcodes for data storage.
-map_op[".long_*"] = function(params)
- if not params then return "imm..." end
- for _,p in ipairs(params) do
- local n = tonumber(p)
- if not n then werror("bad immediate `"..p.."'") end
- if n < 0 then n = n + 2^32 end
- wputw(n)
- if secpos+2 > maxsecpos then wflush() end
- end
-end
-
--- Alignment pseudo-opcode.
-map_op[".align_1"] = function(params)
- if not params then return "numpow2" end
- if secpos+1 > maxsecpos then wflush() end
- local align = tonumber(params[1])
- if align then
- local x = align
- -- Must be a power of 2 in the range (2 ... 256).
- for i=1,8 do
- x = x / 2
- if x == 1 then
- waction("ALIGN", align-1, nil, 1) -- Action byte is 2**n-1.
- return
- end
- end
- end
- werror("bad alignment")
-end
-
-------------------------------------------------------------------------------
-
--- Pseudo-opcode for (primitive) type definitions (map to C types).
-map_op[".type_3"] = function(params, nparams)
- if not params then
- return nparams == 2 and "name, ctype" or "name, ctype, reg"
- end
- local name, ctype, reg = params[1], params[2], params[3]
- if not match(name, "^[%a_][%w_]*$") then
- werror("bad type name `"..name.."'")
- end
- local tp = map_type[name]
- if tp then
- werror("duplicate type `"..name.."'")
- end
- -- Add #type to defines. A bit unclean to put it in map_archdef.
- map_archdef["#"..name] = "sizeof("..ctype..")"
- -- Add new type and emit shortcut define.
- local num = ctypenum + 1
- map_type[name] = {
- ctype = ctype,
- ctypefmt = format("Dt%X(%%s)", num),
- reg = reg,
- }
- wline(format("#define Dt%X(_V) (int)(ptrdiff_t)&(((%s *)0)_V)", num, ctype))
- ctypenum = num
-end
-map_op[".type_2"] = map_op[".type_3"]
-
--- Dump type definitions.
-local function dumptypes(out, lvl)
- local t = {}
- for name in pairs(map_type) do t[#t+1] = name end
- sort(t)
- out:write("Type definitions:\n")
- for _,name in ipairs(t) do
- local tp = map_type[name]
- local reg = tp.reg or ""
- out:write(format(" %-20s %-20s %s\n", name, tp.ctype, reg))
- end
- out:write("\n")
-end
-
-------------------------------------------------------------------------------
-
--- Set the current section.
-function _M.section(num)
- waction("SECTION", num)
- wflush(true) -- SECTION is a terminal action.
-end
-
-------------------------------------------------------------------------------
-
--- Dump architecture description.
-function _M.dumparch(out)
- out:write(format("DynASM %s version %s, released %s\n\n",
- _info.arch, _info.version, _info.release))
- dumpactions(out)
-end
-
--- Dump all user defined elements.
-function _M.dumpdef(out, lvl)
- dumptypes(out, lvl)
- dumpglobals(out, lvl)
- dumpexterns(out, lvl)
-end
-
-------------------------------------------------------------------------------
-
--- Pass callbacks from/to the DynASM core.
-function _M.passcb(wl, we, wf, ww)
- wline, werror, wfatal, wwarn = wl, we, wf, ww
- return wflush
-end
-
--- Setup the arch-specific module.
-function _M.setup(arch, opt)
- g_arch, g_opt = arch, opt
-end
-
--- Merge the core maps and the arch-specific maps.
-function _M.mergemaps(map_coreop, map_def)
- setmetatable(map_op, { __index = map_coreop })
- setmetatable(map_def, { __index = map_archdef })
- return map_op, map_def
-end
-
-return _M
-
-------------------------------------------------------------------------------
-
diff --git a/core/src/luajit/dynasm/dasm_ppc.h b/core/src/luajit/dynasm/dasm_ppc.h
deleted file mode 100644
index 7df493654..000000000
--- a/core/src/luajit/dynasm/dasm_ppc.h
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
-** DynASM PPC encoding engine.
-** Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-** Released under the MIT license. See dynasm.lua for full copyright notice.
-*/
-
-#include <stddef.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdlib.h>
-
-#define DASM_ARCH "ppc"
-
-#ifndef DASM_EXTERN
-#define DASM_EXTERN(a,b,c,d) 0
-#endif
-
-/* Action definitions. */
-enum {
- DASM_STOP, DASM_SECTION, DASM_ESC, DASM_REL_EXT,
- /* The following actions need a buffer position. */
- DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,
- /* The following actions also have an argument. */
- DASM_REL_PC, DASM_LABEL_PC, DASM_IMM,
- DASM__MAX
-};
-
-/* Maximum number of section buffer positions for a single dasm_put() call. */
-#define DASM_MAXSECPOS 25
-
-/* DynASM encoder status codes. Action list offset or number are or'ed in. */
-#define DASM_S_OK 0x00000000
-#define DASM_S_NOMEM 0x01000000
-#define DASM_S_PHASE 0x02000000
-#define DASM_S_MATCH_SEC 0x03000000
-#define DASM_S_RANGE_I 0x11000000
-#define DASM_S_RANGE_SEC 0x12000000
-#define DASM_S_RANGE_LG 0x13000000
-#define DASM_S_RANGE_PC 0x14000000
-#define DASM_S_RANGE_REL 0x15000000
-#define DASM_S_UNDEF_LG 0x21000000
-#define DASM_S_UNDEF_PC 0x22000000
-
-/* Macros to convert positions (8 bit section + 24 bit index). */
-#define DASM_POS2IDX(pos) ((pos)&0x00ffffff)
-#define DASM_POS2BIAS(pos) ((pos)&0xff000000)
-#define DASM_SEC2POS(sec) ((sec)<<24)
-#define DASM_POS2SEC(pos) ((pos)>>24)
-#define DASM_POS2PTR(D, pos) (D->sections[DASM_POS2SEC(pos)].rbuf + (pos))
-
-/* Action list type. */
-typedef const unsigned int *dasm_ActList;
-
-/* Per-section structure. */
-typedef struct dasm_Section {
- int *rbuf; /* Biased buffer pointer (negative section bias). */
- int *buf; /* True buffer pointer. */
- size_t bsize; /* Buffer size in bytes. */
- int pos; /* Biased buffer position. */
- int epos; /* End of biased buffer position - max single put. */
- int ofs; /* Byte offset into section. */
-} dasm_Section;
-
-/* Core structure holding the DynASM encoding state. */
-struct dasm_State {
- size_t psize; /* Allocated size of this structure. */
- dasm_ActList actionlist; /* Current actionlist pointer. */
- int *lglabels; /* Local/global chain/pos ptrs. */
- size_t lgsize;
- int *pclabels; /* PC label chains/pos ptrs. */
- size_t pcsize;
- void **globals; /* Array of globals (bias -10). */
- dasm_Section *section; /* Pointer to active section. */
- size_t codesize; /* Total size of all code sections. */
- int maxsection; /* 0 <= sectionidx < maxsection. */
- int status; /* Status code. */
- dasm_Section sections[1]; /* All sections. Alloc-extended. */
-};
-
-/* The size of the core structure depends on the max. number of sections. */
-#define DASM_PSZ(ms) (sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))
-
-
-/* Initialize DynASM state. */
-void dasm_init(Dst_DECL, int maxsection)
-{
- dasm_State *D;
- size_t psz = 0;
- int i;
- Dst_REF = NULL;
- DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
- D = Dst_REF;
- D->psize = psz;
- D->lglabels = NULL;
- D->lgsize = 0;
- D->pclabels = NULL;
- D->pcsize = 0;
- D->globals = NULL;
- D->maxsection = maxsection;
- for (i = 0; i < maxsection; i++) {
- D->sections[i].buf = NULL; /* Need this for pass3. */
- D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);
- D->sections[i].bsize = 0;
- D->sections[i].epos = 0; /* Wrong, but is recalculated after resize. */
- }
-}
-
-/* Free DynASM state. */
-void dasm_free(Dst_DECL)
-{
- dasm_State *D = Dst_REF;
- int i;
- for (i = 0; i < D->maxsection; i++)
- if (D->sections[i].buf)
- DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);
- if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);
- if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);
- DASM_M_FREE(Dst, D, D->psize);
-}
-
-/* Setup global label array. Must be called before dasm_setup(). */
-void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
-{
- dasm_State *D = Dst_REF;
- D->globals = gl - 10; /* Negative bias to compensate for locals. */
- DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
-}
-
-/* Grow PC label array. Can be called after dasm_setup(), too. */
-void dasm_growpc(Dst_DECL, unsigned int maxpc)
-{
- dasm_State *D = Dst_REF;
- size_t osz = D->pcsize;
- DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));
- memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);
-}
-
-/* Setup encoder. */
-void dasm_setup(Dst_DECL, const void *actionlist)
-{
- dasm_State *D = Dst_REF;
- int i;
- D->actionlist = (dasm_ActList)actionlist;
- D->status = DASM_S_OK;
- D->section = &D->sections[0];
- memset((void *)D->lglabels, 0, D->lgsize);
- if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
- for (i = 0; i < D->maxsection; i++) {
- D->sections[i].pos = DASM_SEC2POS(i);
- D->sections[i].ofs = 0;
- }
-}
-
-
-#ifdef DASM_CHECKS
-#define CK(x, st) \
- do { if (!(x)) { \
- D->status = DASM_S_##st|(p-D->actionlist-1); return; } } while (0)
-#define CKPL(kind, st) \
- do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \
- D->status = DASM_S_RANGE_##st|(p-D->actionlist-1); return; } } while (0)
-#else
-#define CK(x, st) ((void)0)
-#define CKPL(kind, st) ((void)0)
-#endif
-
-/* Pass 1: Store actions and args, link branches/labels, estimate offsets. */
-void dasm_put(Dst_DECL, int start, ...)
-{
- va_list ap;
- dasm_State *D = Dst_REF;
- dasm_ActList p = D->actionlist + start;
- dasm_Section *sec = D->section;
- int pos = sec->pos, ofs = sec->ofs;
- int *b;
-
- if (pos >= sec->epos) {
- DASM_M_GROW(Dst, int, sec->buf, sec->bsize,
- sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));
- sec->rbuf = sec->buf - DASM_POS2BIAS(pos);
- sec->epos = (int)sec->bsize/sizeof(int) - DASM_MAXSECPOS+DASM_POS2BIAS(pos);
- }
-
- b = sec->rbuf;
- b[pos++] = start;
-
- va_start(ap, start);
- while (1) {
- unsigned int ins = *p++;
- unsigned int action = (ins >> 16);
- if (action >= DASM__MAX) {
- ofs += 4;
- } else {
- int *pl, n = action >= DASM_REL_PC ? va_arg(ap, int) : 0;
- switch (action) {
- case DASM_STOP: goto stop;
- case DASM_SECTION:
- n = (ins & 255); CK(n < D->maxsection, RANGE_SEC);
- D->section = &D->sections[n]; goto stop;
- case DASM_ESC: p++; ofs += 4; break;
- case DASM_REL_EXT: break;
- case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break;
- case DASM_REL_LG:
- n = (ins & 2047) - 10; pl = D->lglabels + n;
- /* Bkwd rel or global. */
- if (n >= 0) { CK(n>=10||*pl<0, RANGE_LG); CKPL(lg, LG); goto putrel; }
- pl += 10; n = *pl;
- if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
- goto linkrel;
- case DASM_REL_PC:
- pl = D->pclabels + n; CKPL(pc, PC);
- putrel:
- n = *pl;
- if (n < 0) { /* Label exists. Get label pos and store it. */
- b[pos] = -n;
- } else {
- linkrel:
- b[pos] = n; /* Else link to rel chain, anchored at label. */
- *pl = pos;
- }
- pos++;
- break;
- case DASM_LABEL_LG:
- pl = D->lglabels + (ins & 2047) - 10; CKPL(lg, LG); goto putlabel;
- case DASM_LABEL_PC:
- pl = D->pclabels + n; CKPL(pc, PC);
- putlabel:
- n = *pl; /* n > 0: Collapse rel chain and replace with label pos. */
- while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos;
- }
- *pl = -pos; /* Label exists now. */
- b[pos++] = ofs; /* Store pass1 offset estimate. */
- break;
- case DASM_IMM:
-#ifdef DASM_CHECKS
- CK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I);
-#endif
- n >>= ((ins>>10)&31);
-#ifdef DASM_CHECKS
- if (ins & 0x8000)
- CK(((n + (1<<(((ins>>5)&31)-1)))>>((ins>>5)&31)) == 0, RANGE_I);
- else
- CK((n>>((ins>>5)&31)) == 0, RANGE_I);
-#endif
- b[pos++] = n;
- break;
- }
- }
- }
-stop:
- va_end(ap);
- sec->pos = pos;
- sec->ofs = ofs;
-}
-#undef CK
-
-/* Pass 2: Link sections, shrink aligns, fix label offsets. */
-int dasm_link(Dst_DECL, size_t *szp)
-{
- dasm_State *D = Dst_REF;
- int secnum;
- int ofs = 0;
-
-#ifdef DASM_CHECKS
- *szp = 0;
- if (D->status != DASM_S_OK) return D->status;
- {
- int pc;
- for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)
- if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;
- }
-#endif
-
- { /* Handle globals not defined in this translation unit. */
- int idx;
- for (idx = 20; idx*sizeof(int) < D->lgsize; idx++) {
- int n = D->lglabels[idx];
- /* Undefined label: Collapse rel chain and replace with marker (< 0). */
- while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
- }
- }
-
- /* Combine all code sections. No support for data sections (yet). */
- for (secnum = 0; secnum < D->maxsection; secnum++) {
- dasm_Section *sec = D->sections + secnum;
- int *b = sec->rbuf;
- int pos = DASM_SEC2POS(secnum);
- int lastpos = sec->pos;
-
- while (pos != lastpos) {
- dasm_ActList p = D->actionlist + b[pos++];
- while (1) {
- unsigned int ins = *p++;
- unsigned int action = (ins >> 16);
- switch (action) {
- case DASM_STOP: case DASM_SECTION: goto stop;
- case DASM_ESC: p++; break;
- case DASM_REL_EXT: break;
- case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;
- case DASM_REL_LG: case DASM_REL_PC: pos++; break;
- case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
- case DASM_IMM: pos++; break;
- }
- }
- stop: (void)0;
- }
- ofs += sec->ofs; /* Next section starts right after current section. */
- }
-
- D->codesize = ofs; /* Total size of all code sections */
- *szp = ofs;
- return DASM_S_OK;
-}
-
-#ifdef DASM_CHECKS
-#define CK(x, st) \
- do { if (!(x)) return DASM_S_##st|(p-D->actionlist-1); } while (0)
-#else
-#define CK(x, st) ((void)0)
-#endif
-
-/* Pass 3: Encode sections. */
-int dasm_encode(Dst_DECL, void *buffer)
-{
- dasm_State *D = Dst_REF;
- char *base = (char *)buffer;
- unsigned int *cp = (unsigned int *)buffer;
- int secnum;
-
- /* Encode all code sections. No support for data sections (yet). */
- for (secnum = 0; secnum < D->maxsection; secnum++) {
- dasm_Section *sec = D->sections + secnum;
- int *b = sec->buf;
- int *endb = sec->rbuf + sec->pos;
-
- while (b != endb) {
- dasm_ActList p = D->actionlist + *b++;
- while (1) {
- unsigned int ins = *p++;
- unsigned int action = (ins >> 16);
- int n = (action >= DASM_ALIGN && action < DASM__MAX) ? *b++ : 0;
- switch (action) {
- case DASM_STOP: case DASM_SECTION: goto stop;
- case DASM_ESC: *cp++ = *p++; break;
- case DASM_REL_EXT:
- n = DASM_EXTERN(Dst, (unsigned char *)cp, (ins & 2047), 1) - 4;
- goto patchrel;
- case DASM_ALIGN:
- ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0x60000000;
- break;
- case DASM_REL_LG:
- CK(n >= 0, UNDEF_LG);
- case DASM_REL_PC:
- CK(n >= 0, UNDEF_PC);
- n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base);
- patchrel:
- CK((n & 3) == 0 &&
- (((n+4) + ((ins & 2048) ? 0x00008000 : 0x02000000)) >>
- ((ins & 2048) ? 16 : 26)) == 0, RANGE_REL);
- cp[-1] |= ((n+4) & ((ins & 2048) ? 0x0000fffc: 0x03fffffc));
- break;
- case DASM_LABEL_LG:
- ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);
- break;
- case DASM_LABEL_PC: break;
- case DASM_IMM:
- cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31);
- break;
- default: *cp++ = ins; break;
- }
- }
- stop: (void)0;
- }
- }
-
- if (base + D->codesize != (char *)cp) /* Check for phase errors. */
- return DASM_S_PHASE;
- return DASM_S_OK;
-}
-#undef CK
-
-/* Get PC label offset. */
-int dasm_getpclabel(Dst_DECL, unsigned int pc)
-{
- dasm_State *D = Dst_REF;
- if (pc*sizeof(int) < D->pcsize) {
- int pos = D->pclabels[pc];
- if (pos < 0) return *DASM_POS2PTR(D, -pos);
- if (pos > 0) return -1; /* Undefined. */
- }
- return -2; /* Unused or out of range. */
-}
-
-#ifdef DASM_CHECKS
-/* Optional sanity checker to call between isolated encoding steps. */
-int dasm_checkstep(Dst_DECL, int secmatch)
-{
- dasm_State *D = Dst_REF;
- if (D->status == DASM_S_OK) {
- int i;
- for (i = 1; i <= 9; i++) {
- if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_LG|i; break; }
- D->lglabels[i] = 0;
- }
- }
- if (D->status == DASM_S_OK && secmatch >= 0 &&
- D->section != &D->sections[secmatch])
- D->status = DASM_S_MATCH_SEC|(D->section-D->sections);
- return D->status;
-}
-#endif
-
diff --git a/core/src/luajit/dynasm/dasm_ppc.lua b/core/src/luajit/dynasm/dasm_ppc.lua
deleted file mode 100644
index 91f4ff9a4..000000000
--- a/core/src/luajit/dynasm/dasm_ppc.lua
+++ /dev/null
@@ -1,1249 +0,0 @@
-------------------------------------------------------------------------------
--- DynASM PPC module.
---
--- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
--- See dynasm.lua for full copyright notice.
-------------------------------------------------------------------------------
-
--- Module information:
-local _info = {
- arch = "ppc",
- description = "DynASM PPC module",
- version = "1.3.0",
- vernum = 10300,
- release = "2011-05-05",
- author = "Mike Pall",
- license = "MIT",
-}
-
--- Exported glue functions for the arch-specific module.
-local _M = { _info = _info }
-
--- Cache library functions.
-local type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs
-local assert, setmetatable = assert, setmetatable
-local _s = string
-local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
-local match, gmatch = _s.match, _s.gmatch
-local concat, sort = table.concat, table.sort
-local bit = bit or require("bit")
-local band, shl, shr, sar = bit.band, bit.lshift, bit.rshift, bit.arshift
-local tohex = bit.tohex
-
--- Inherited tables and callbacks.
-local g_opt, g_arch
-local wline, werror, wfatal, wwarn
-
--- Action name list.
--- CHECK: Keep this in sync with the C code!
-local action_names = {
- "STOP", "SECTION", "ESC", "REL_EXT",
- "ALIGN", "REL_LG", "LABEL_LG",
- "REL_PC", "LABEL_PC", "IMM",
-}
-
--- Maximum number of section buffer positions for dasm_put().
--- CHECK: Keep this in sync with the C code!
-local maxsecpos = 25 -- Keep this low, to avoid excessively long C lines.
-
--- Action name -> action number.
-local map_action = {}
-for n,name in ipairs(action_names) do
- map_action[name] = n-1
-end
-
--- Action list buffer.
-local actlist = {}
-
--- Argument list for next dasm_put(). Start with offset 0 into action list.
-local actargs = { 0 }
-
--- Current number of section buffer positions for dasm_put().
-local secpos = 1
-
-------------------------------------------------------------------------------
-
--- Dump action names and numbers.
-local function dumpactions(out)
- out:write("DynASM encoding engine action codes:\n")
- for n,name in ipairs(action_names) do
- local num = map_action[name]
- out:write(format(" %-10s %02X %d\n", name, num, num))
- end
- out:write("\n")
-end
-
--- Write action list buffer as a huge static C array.
-local function writeactions(out, name)
- local nn = #actlist
- if nn == 0 then nn = 1; actlist[0] = map_action.STOP end
- out:write("static const unsigned int ", name, "[", nn, "] = {\n")
- for i = 1,nn-1 do
- assert(out:write("0x", tohex(actlist[i]), ",\n"))
- end
- assert(out:write("0x", tohex(actlist[nn]), "\n};\n\n"))
-end
-
-------------------------------------------------------------------------------
-
--- Add word to action list.
-local function wputxw(n)
- assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, "word out of range")
- actlist[#actlist+1] = n
-end
-
--- Add action to list with optional arg. Advance buffer pos, too.
-local function waction(action, val, a, num)
- local w = assert(map_action[action], "bad action name `"..action.."'")
- wputxw(w * 0x10000 + (val or 0))
- if a then actargs[#actargs+1] = a end
- if a or num then secpos = secpos + (num or 1) end
-end
-
--- Flush action list (intervening C code or buffer pos overflow).
-local function wflush(term)
- if #actlist == actargs[1] then return end -- Nothing to flush.
- if not term then waction("STOP") end -- Terminate action list.
- wline(format("dasm_put(Dst, %s);", concat(actargs, ", ")), true)
- actargs = { #actlist } -- Actionlist offset is 1st arg to next dasm_put().
- secpos = 1 -- The actionlist offset occupies a buffer position, too.
-end
-
--- Put escaped word.
-local function wputw(n)
- if n <= 0xffffff then waction("ESC") end
- wputxw(n)
-end
-
--- Reserve position for word.
-local function wpos()
- local pos = #actlist+1
- actlist[pos] = ""
- return pos
-end
-
--- Store word to reserved position.
-local function wputpos(pos, n)
- assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, "word out of range")
- actlist[pos] = n
-end
-
-------------------------------------------------------------------------------
-
--- Global label name -> global label number. With auto assignment on 1st use.
-local next_global = 20
-local map_global = setmetatable({}, { __index = function(t, name)
- if not match(name, "^[%a_][%w_]*$") then werror("bad global label") end
- local n = next_global
- if n > 2047 then werror("too many global labels") end
- next_global = n + 1
- t[name] = n
- return n
-end})
-
--- Dump global labels.
-local function dumpglobals(out, lvl)
- local t = {}
- for name, n in pairs(map_global) do t[n] = name end
- out:write("Global labels:\n")
- for i=20,next_global-1 do
- out:write(format(" %s\n", t[i]))
- end
- out:write("\n")
-end
-
--- Write global label enum.
-local function writeglobals(out, prefix)
- local t = {}
- for name, n in pairs(map_global) do t[n] = name end
- out:write("enum {\n")
- for i=20,next_global-1 do
- out:write(" ", prefix, t[i], ",\n")
- end
- out:write(" ", prefix, "_MAX\n};\n")
-end
-
--- Write global label names.
-local function writeglobalnames(out, name)
- local t = {}
- for name, n in pairs(map_global) do t[n] = name end
- out:write("static const char *const ", name, "[] = {\n")
- for i=20,next_global-1 do
- out:write(" \"", t[i], "\",\n")
- end
- out:write(" (const char *)0\n};\n")
-end
-
-------------------------------------------------------------------------------
-
--- Extern label name -> extern label number. With auto assignment on 1st use.
-local next_extern = 0
-local map_extern_ = {}
-local map_extern = setmetatable({}, { __index = function(t, name)
- -- No restrictions on the name for now.
- local n = next_extern
- if n > 2047 then werror("too many extern labels") end
- next_extern = n + 1
- t[name] = n
- map_extern_[n] = name
- return n
-end})
-
--- Dump extern labels.
-local function dumpexterns(out, lvl)
- out:write("Extern labels:\n")
- for i=0,next_extern-1 do
- out:write(format(" %s\n", map_extern_[i]))
- end
- out:write("\n")
-end
-
--- Write extern label names.
-local function writeexternnames(out, name)
- out:write("static const char *const ", name, "[] = {\n")
- for i=0,next_extern-1 do
- out:write(" \"", map_extern_[i], "\",\n")
- end
- out:write(" (const char *)0\n};\n")
-end
-
-------------------------------------------------------------------------------
-
--- Arch-specific maps.
-local map_archdef = { sp = "r1" } -- Ext. register name -> int. name.
-
-local map_type = {} -- Type name -> { ctype, reg }
-local ctypenum = 0 -- Type number (for Dt... macros).
-
--- Reverse defines for registers.
-function _M.revdef(s)
- if s == "r1" then return "sp" end
- return s
-end
-
-local map_cond = {
- lt = 0, gt = 1, eq = 2, so = 3,
- ge = 4, le = 5, ne = 6, ns = 7,
-}
-
-------------------------------------------------------------------------------
-
--- Template strings for PPC instructions.
-local map_op = {
- tdi_3 = "08000000ARI",
- twi_3 = "0c000000ARI",
- mulli_3 = "1c000000RRI",
- subfic_3 = "20000000RRI",
- cmplwi_3 = "28000000XRU",
- cmplwi_2 = "28000000-RU",
- cmpldi_3 = "28200000XRU",
- cmpldi_2 = "28200000-RU",
- cmpwi_3 = "2c000000XRI",
- cmpwi_2 = "2c000000-RI",
- cmpdi_3 = "2c200000XRI",
- cmpdi_2 = "2c200000-RI",
- addic_3 = "30000000RRI",
- ["addic._3"] = "34000000RRI",
- addi_3 = "38000000RR0I",
- li_2 = "38000000RI",
- la_2 = "38000000RD",
- addis_3 = "3c000000RR0I",
- lis_2 = "3c000000RI",
- lus_2 = "3c000000RU",
- bc_3 = "40000000AAK",
- bcl_3 = "40000001AAK",
- bdnz_1 = "42000000K",
- bdz_1 = "42400000K",
- sc_0 = "44000000",
- b_1 = "48000000J",
- bl_1 = "48000001J",
- rlwimi_5 = "50000000RR~AAA.",
- rlwinm_5 = "54000000RR~AAA.",
- rlwnm_5 = "5c000000RR~RAA.",
- ori_3 = "60000000RR~U",
- nop_0 = "60000000",
- oris_3 = "64000000RR~U",
- xori_3 = "68000000RR~U",
- xoris_3 = "6c000000RR~U",
- ["andi._3"] = "70000000RR~U",
- ["andis._3"] = "74000000RR~U",
- lwz_2 = "80000000RD",
- lwzu_2 = "84000000RD",
- lbz_2 = "88000000RD",
- lbzu_2 = "8c000000RD",
- stw_2 = "90000000RD",
- stwu_2 = "94000000RD",
- stb_2 = "98000000RD",
- stbu_2 = "9c000000RD",
- lhz_2 = "a0000000RD",
- lhzu_2 = "a4000000RD",
- lha_2 = "a8000000RD",
- lhau_2 = "ac000000RD",
- sth_2 = "b0000000RD",
- sthu_2 = "b4000000RD",
- lmw_2 = "b8000000RD",
- stmw_2 = "bc000000RD",
- lfs_2 = "c0000000FD",
- lfsu_2 = "c4000000FD",
- lfd_2 = "c8000000FD",
- lfdu_2 = "cc000000FD",
- stfs_2 = "d0000000FD",
- stfsu_2 = "d4000000FD",
- stfd_2 = "d8000000FD",
- stfdu_2 = "dc000000FD",
- ld_2 = "e8000000RD", -- NYI: displacement must be divisible by 4.
- ldu_2 = "e8000001RD",
- lwa_2 = "e8000002RD",
- std_2 = "f8000000RD",
- stdu_2 = "f8000001RD",
-
- -- Primary opcode 19:
- mcrf_2 = "4c000000XX",
- isync_0 = "4c00012c",
- crnor_3 = "4c000042CCC",
- crnot_2 = "4c000042CC=",
- crandc_3 = "4c000102CCC",
- crxor_3 = "4c000182CCC",
- crclr_1 = "4c000182C==",
- crnand_3 = "4c0001c2CCC",
- crand_3 = "4c000202CCC",
- creqv_3 = "4c000242CCC",
- crset_1 = "4c000242C==",
- crorc_3 = "4c000342CCC",
- cror_3 = "4c000382CCC",
- crmove_2 = "4c000382CC=",
- bclr_2 = "4c000020AA",
- bclrl_2 = "4c000021AA",
- bcctr_2 = "4c000420AA",
- bcctrl_2 = "4c000421AA",
- blr_0 = "4e800020",
- blrl_0 = "4e800021",
- bctr_0 = "4e800420",
- bctrl_0 = "4e800421",
-
- -- Primary opcode 31:
- cmpw_3 = "7c000000XRR",
- cmpw_2 = "7c000000-RR",
- cmpd_3 = "7c200000XRR",
- cmpd_2 = "7c200000-RR",
- tw_3 = "7c000008ARR",
- subfc_3 = "7c000010RRR.",
- subc_3 = "7c000010RRR~.",
- mulhdu_3 = "7c000012RRR.",
- addc_3 = "7c000014RRR.",
- mulhwu_3 = "7c000016RRR.",
- isel_4 = "7c00001eRRRC",
- isellt_3 = "7c00001eRRR",
- iselgt_3 = "7c00005eRRR",
- iseleq_3 = "7c00009eRRR",
- mfcr_1 = "7c000026R",
- mfocrf_2 = "7c100026RG",
- mtcrf_2 = "7c000120GR",
- mtocrf_2 = "7c100120GR",
- lwarx_3 = "7c000028RR0R",
- ldx_3 = "7c00002aRR0R",
- lwzx_3 = "7c00002eRR0R",
- slw_3 = "7c000030RR~R.",
- cntlzw_2 = "7c000034RR~",
- sld_3 = "7c000036RR~R.",
- and_3 = "7c000038RR~R.",
- cmplw_3 = "7c000040XRR",
- cmplw_2 = "7c000040-RR",
- cmpld_3 = "7c200040XRR",
- cmpld_2 = "7c200040-RR",
- subf_3 = "7c000050RRR.",
- sub_3 = "7c000050RRR~.",
- ldux_3 = "7c00006aRR0R",
- dcbst_2 = "7c00006c-RR",
- lwzux_3 = "7c00006eRR0R",
- cntlzd_2 = "7c000074RR~",
- andc_3 = "7c000078RR~R.",
- td_3 = "7c000088ARR",
- mulhd_3 = "7c000092RRR.",
- mulhw_3 = "7c000096RRR.",
- ldarx_3 = "7c0000a8RR0R",
- dcbf_2 = "7c0000ac-RR",
- lbzx_3 = "7c0000aeRR0R",
- neg_2 = "7c0000d0RR.",
- lbzux_3 = "7c0000eeRR0R",
- popcntb_2 = "7c0000f4RR~",
- not_2 = "7c0000f8RR~%.",
- nor_3 = "7c0000f8RR~R.",
- subfe_3 = "7c000110RRR.",
- sube_3 = "7c000110RRR~.",
- adde_3 = "7c000114RRR.",
- stdx_3 = "7c00012aRR0R",
- stwcx_3 = "7c00012cRR0R.",
- stwx_3 = "7c00012eRR0R",
- prtyw_2 = "7c000134RR~",
- stdux_3 = "7c00016aRR0R",
- stwux_3 = "7c00016eRR0R",
- prtyd_2 = "7c000174RR~",
- subfze_2 = "7c000190RR.",
- addze_2 = "7c000194RR.",
- stdcx_3 = "7c0001acRR0R.",
- stbx_3 = "7c0001aeRR0R",
- subfme_2 = "7c0001d0RR.",
- mulld_3 = "7c0001d2RRR.",
- addme_2 = "7c0001d4RR.",
- mullw_3 = "7c0001d6RRR.",
- dcbtst_2 = "7c0001ec-RR",
- stbux_3 = "7c0001eeRR0R",
- add_3 = "7c000214RRR.",
- dcbt_2 = "7c00022c-RR",
- lhzx_3 = "7c00022eRR0R",
- eqv_3 = "7c000238RR~R.",
- eciwx_3 = "7c00026cRR0R",
- lhzux_3 = "7c00026eRR0R",
- xor_3 = "7c000278RR~R.",
- mfspefscr_1 = "7c0082a6R",
- mfxer_1 = "7c0102a6R",
- mflr_1 = "7c0802a6R",
- mfctr_1 = "7c0902a6R",
- lwax_3 = "7c0002aaRR0R",
- lhax_3 = "7c0002aeRR0R",
- mftb_1 = "7c0c42e6R",
- mftbu_1 = "7c0d42e6R",
- lwaux_3 = "7c0002eaRR0R",
- lhaux_3 = "7c0002eeRR0R",
- sthx_3 = "7c00032eRR0R",
- orc_3 = "7c000338RR~R.",
- ecowx_3 = "7c00036cRR0R",
- sthux_3 = "7c00036eRR0R",
- or_3 = "7c000378RR~R.",
- mr_2 = "7c000378RR~%.",
- divdu_3 = "7c000392RRR.",
- divwu_3 = "7c000396RRR.",
- mtspefscr_1 = "7c0083a6R",
- mtxer_1 = "7c0103a6R",
- mtlr_1 = "7c0803a6R",
- mtctr_1 = "7c0903a6R",
- dcbi_2 = "7c0003ac-RR",
- nand_3 = "7c0003b8RR~R.",
- divd_3 = "7c0003d2RRR.",
- divw_3 = "7c0003d6RRR.",
- cmpb_3 = "7c0003f8RR~R.",
- mcrxr_1 = "7c000400X",
- subfco_3 = "7c000410RRR.",
- subco_3 = "7c000410RRR~.",
- addco_3 = "7c000414RRR.",
- ldbrx_3 = "7c000428RR0R",
- lswx_3 = "7c00042aRR0R",
- lwbrx_3 = "7c00042cRR0R",
- lfsx_3 = "7c00042eFR0R",
- srw_3 = "7c000430RR~R.",
- srd_3 = "7c000436RR~R.",
- subfo_3 = "7c000450RRR.",
- subo_3 = "7c000450RRR~.",
- lfsux_3 = "7c00046eFR0R",
- lswi_3 = "7c0004aaRR0A",
- sync_0 = "7c0004ac",
- lwsync_0 = "7c2004ac",
- ptesync_0 = "7c4004ac",
- lfdx_3 = "7c0004aeFR0R",
- nego_2 = "7c0004d0RR.",
- lfdux_3 = "7c0004eeFR0R",
- subfeo_3 = "7c000510RRR.",
- subeo_3 = "7c000510RRR~.",
- addeo_3 = "7c000514RRR.",
- stdbrx_3 = "7c000528RR0R",
- stswx_3 = "7c00052aRR0R",
- stwbrx_3 = "7c00052cRR0R",
- stfsx_3 = "7c00052eFR0R",
- stfsux_3 = "7c00056eFR0R",
- subfzeo_2 = "7c000590RR.",
- addzeo_2 = "7c000594RR.",
- stswi_3 = "7c0005aaRR0A",
- stfdx_3 = "7c0005aeFR0R",
- subfmeo_2 = "7c0005d0RR.",
- mulldo_3 = "7c0005d2RRR.",
- addmeo_2 = "7c0005d4RR.",
- mullwo_3 = "7c0005d6RRR.",
- dcba_2 = "7c0005ec-RR",
- stfdux_3 = "7c0005eeFR0R",
- addo_3 = "7c000614RRR.",
- lhbrx_3 = "7c00062cRR0R",
- sraw_3 = "7c000630RR~R.",
- srad_3 = "7c000634RR~R.",
- srawi_3 = "7c000670RR~A.",
- sradi_3 = "7c000674RR~H.",
- eieio_0 = "7c0006ac",
- lfiwax_3 = "7c0006aeFR0R",
- sthbrx_3 = "7c00072cRR0R",
- extsh_2 = "7c000734RR~.",
- extsb_2 = "7c000774RR~.",
- divduo_3 = "7c000792RRR.",
- divwou_3 = "7c000796RRR.",
- icbi_2 = "7c0007ac-RR",
- stfiwx_3 = "7c0007aeFR0R",
- extsw_2 = "7c0007b4RR~.",
- divdo_3 = "7c0007d2RRR.",
- divwo_3 = "7c0007d6RRR.",
- dcbz_2 = "7c0007ec-RR",
-
- -- Primary opcode 30:
- rldicl_4 = "78000000RR~HM.",
- rldicr_4 = "78000004RR~HM.",
- rldic_4 = "78000008RR~HM.",
- rldimi_4 = "7800000cRR~HM.",
- rldcl_4 = "78000010RR~RM.",
- rldcr_4 = "78000012RR~RM.",
-
- -- Primary opcode 59:
- fdivs_3 = "ec000024FFF.",
- fsubs_3 = "ec000028FFF.",
- fadds_3 = "ec00002aFFF.",
- fsqrts_2 = "ec00002cF-F.",
- fres_2 = "ec000030F-F.",
- fmuls_3 = "ec000032FF-F.",
- frsqrtes_2 = "ec000034F-F.",
- fmsubs_4 = "ec000038FFFF~.",
- fmadds_4 = "ec00003aFFFF~.",
- fnmsubs_4 = "ec00003cFFFF~.",
- fnmadds_4 = "ec00003eFFFF~.",
-
- -- Primary opcode 63:
- fdiv_3 = "fc000024FFF.",
- fsub_3 = "fc000028FFF.",
- fadd_3 = "fc00002aFFF.",
- fsqrt_2 = "fc00002cF-F.",
- fsel_4 = "fc00002eFFFF~.",
- fre_2 = "fc000030F-F.",
- fmul_3 = "fc000032FF-F.",
- frsqrte_2 = "fc000034F-F.",
- fmsub_4 = "fc000038FFFF~.",
- fmadd_4 = "fc00003aFFFF~.",
- fnmsub_4 = "fc00003cFFFF~.",
- fnmadd_4 = "fc00003eFFFF~.",
- fcmpu_3 = "fc000000XFF",
- fcpsgn_3 = "fc000010FFF.",
- fcmpo_3 = "fc000040XFF",
- mtfsb1_1 = "fc00004cA",
- fneg_2 = "fc000050F-F.",
- mcrfs_2 = "fc000080XX",
- mtfsb0_1 = "fc00008cA",
- fmr_2 = "fc000090F-F.",
- frsp_2 = "fc000018F-F.",
- fctiw_2 = "fc00001cF-F.",
- fctiwz_2 = "fc00001eF-F.",
- mtfsfi_2 = "fc00010cAA", -- NYI: upshift.
- fnabs_2 = "fc000110F-F.",
- fabs_2 = "fc000210F-F.",
- frin_2 = "fc000310F-F.",
- friz_2 = "fc000350F-F.",
- frip_2 = "fc000390F-F.",
- frim_2 = "fc0003d0F-F.",
- mffs_1 = "fc00048eF.",
- -- NYI: mtfsf, mtfsb0, mtfsb1.
- fctid_2 = "fc00065cF-F.",
- fctidz_2 = "fc00065eF-F.",
- fcfid_2 = "fc00069cF-F.",
-
- -- Primary opcode 4, SPE APU extension:
- evaddw_3 = "10000200RRR",
- evaddiw_3 = "10000202RAR~",
- evsubw_3 = "10000204RRR~",
- evsubiw_3 = "10000206RAR~",
- evabs_2 = "10000208RR",
- evneg_2 = "10000209RR",
- evextsb_2 = "1000020aRR",
- evextsh_2 = "1000020bRR",
- evrndw_2 = "1000020cRR",
- evcntlzw_2 = "1000020dRR",
- evcntlsw_2 = "1000020eRR",
- brinc_3 = "1000020fRRR",
- evand_3 = "10000211RRR",
- evandc_3 = "10000212RRR",
- evxor_3 = "10000216RRR",
- evor_3 = "10000217RRR",
- evmr_2 = "10000217RR=",
- evnor_3 = "10000218RRR",
- evnot_2 = "10000218RR=",
- eveqv_3 = "10000219RRR",
- evorc_3 = "1000021bRRR",
- evnand_3 = "1000021eRRR",
- evsrwu_3 = "10000220RRR",
- evsrws_3 = "10000221RRR",
- evsrwiu_3 = "10000222RRA",
- evsrwis_3 = "10000223RRA",
- evslw_3 = "10000224RRR",
- evslwi_3 = "10000226RRA",
- evrlw_3 = "10000228RRR",
- evsplati_2 = "10000229RS",
- evrlwi_3 = "1000022aRRA",
- evsplatfi_2 = "1000022bRS",
- evmergehi_3 = "1000022cRRR",
- evmergelo_3 = "1000022dRRR",
- evcmpgtu_3 = "10000230XRR",
- evcmpgtu_2 = "10000230-RR",
- evcmpgts_3 = "10000231XRR",
- evcmpgts_2 = "10000231-RR",
- evcmpltu_3 = "10000232XRR",
- evcmpltu_2 = "10000232-RR",
- evcmplts_3 = "10000233XRR",
- evcmplts_2 = "10000233-RR",
- evcmpeq_3 = "10000234XRR",
- evcmpeq_2 = "10000234-RR",
- evsel_4 = "10000278RRRW",
- evsel_3 = "10000278RRR",
- evfsadd_3 = "10000280RRR",
- evfssub_3 = "10000281RRR",
- evfsabs_2 = "10000284RR",
- evfsnabs_2 = "10000285RR",
- evfsneg_2 = "10000286RR",
- evfsmul_3 = "10000288RRR",
- evfsdiv_3 = "10000289RRR",
- evfscmpgt_3 = "1000028cXRR",
- evfscmpgt_2 = "1000028c-RR",
- evfscmplt_3 = "1000028dXRR",
- evfscmplt_2 = "1000028d-RR",
- evfscmpeq_3 = "1000028eXRR",
- evfscmpeq_2 = "1000028e-RR",
- evfscfui_2 = "10000290R-R",
- evfscfsi_2 = "10000291R-R",
- evfscfuf_2 = "10000292R-R",
- evfscfsf_2 = "10000293R-R",
- evfsctui_2 = "10000294R-R",
- evfsctsi_2 = "10000295R-R",
- evfsctuf_2 = "10000296R-R",
- evfsctsf_2 = "10000297R-R",
- evfsctuiz_2 = "10000298R-R",
- evfsctsiz_2 = "1000029aR-R",
- evfststgt_3 = "1000029cXRR",
- evfststgt_2 = "1000029c-RR",
- evfststlt_3 = "1000029dXRR",
- evfststlt_2 = "1000029d-RR",
- evfststeq_3 = "1000029eXRR",
- evfststeq_2 = "1000029e-RR",
- efsadd_3 = "100002c0RRR",
- efssub_3 = "100002c1RRR",
- efsabs_2 = "100002c4RR",
- efsnabs_2 = "100002c5RR",
- efsneg_2 = "100002c6RR",
- efsmul_3 = "100002c8RRR",
- efsdiv_3 = "100002c9RRR",
- efscmpgt_3 = "100002ccXRR",
- efscmpgt_2 = "100002cc-RR",
- efscmplt_3 = "100002cdXRR",
- efscmplt_2 = "100002cd-RR",
- efscmpeq_3 = "100002ceXRR",
- efscmpeq_2 = "100002ce-RR",
- efscfd_2 = "100002cfR-R",
- efscfui_2 = "100002d0R-R",
- efscfsi_2 = "100002d1R-R",
- efscfuf_2 = "100002d2R-R",
- efscfsf_2 = "100002d3R-R",
- efsctui_2 = "100002d4R-R",
- efsctsi_2 = "100002d5R-R",
- efsctuf_2 = "100002d6R-R",
- efsctsf_2 = "100002d7R-R",
- efsctuiz_2 = "100002d8R-R",
- efsctsiz_2 = "100002daR-R",
- efststgt_3 = "100002dcXRR",
- efststgt_2 = "100002dc-RR",
- efststlt_3 = "100002ddXRR",
- efststlt_2 = "100002dd-RR",
- efststeq_3 = "100002deXRR",
- efststeq_2 = "100002de-RR",
- efdadd_3 = "100002e0RRR",
- efdsub_3 = "100002e1RRR",
- efdcfuid_2 = "100002e2R-R",
- efdcfsid_2 = "100002e3R-R",
- efdabs_2 = "100002e4RR",
- efdnabs_2 = "100002e5RR",
- efdneg_2 = "100002e6RR",
- efdmul_3 = "100002e8RRR",
- efddiv_3 = "100002e9RRR",
- efdctuidz_2 = "100002eaR-R",
- efdctsidz_2 = "100002ebR-R",
- efdcmpgt_3 = "100002ecXRR",
- efdcmpgt_2 = "100002ec-RR",
- efdcmplt_3 = "100002edXRR",
- efdcmplt_2 = "100002ed-RR",
- efdcmpeq_3 = "100002eeXRR",
- efdcmpeq_2 = "100002ee-RR",
- efdcfs_2 = "100002efR-R",
- efdcfui_2 = "100002f0R-R",
- efdcfsi_2 = "100002f1R-R",
- efdcfuf_2 = "100002f2R-R",
- efdcfsf_2 = "100002f3R-R",
- efdctui_2 = "100002f4R-R",
- efdctsi_2 = "100002f5R-R",
- efdctuf_2 = "100002f6R-R",
- efdctsf_2 = "100002f7R-R",
- efdctuiz_2 = "100002f8R-R",
- efdctsiz_2 = "100002faR-R",
- efdtstgt_3 = "100002fcXRR",
- efdtstgt_2 = "100002fc-RR",
- efdtstlt_3 = "100002fdXRR",
- efdtstlt_2 = "100002fd-RR",
- efdtsteq_3 = "100002feXRR",
- efdtsteq_2 = "100002fe-RR",
- evlddx_3 = "10000300RR0R",
- evldd_2 = "10000301R8",
- evldwx_3 = "10000302RR0R",
- evldw_2 = "10000303R8",
- evldhx_3 = "10000304RR0R",
- evldh_2 = "10000305R8",
- evlwhex_3 = "10000310RR0R",
- evlwhe_2 = "10000311R4",
- evlwhoux_3 = "10000314RR0R",
- evlwhou_2 = "10000315R4",
- evlwhosx_3 = "10000316RR0R",
- evlwhos_2 = "10000317R4",
- evstddx_3 = "10000320RR0R",
- evstdd_2 = "10000321R8",
- evstdwx_3 = "10000322RR0R",
- evstdw_2 = "10000323R8",
- evstdhx_3 = "10000324RR0R",
- evstdh_2 = "10000325R8",
- evstwhex_3 = "10000330RR0R",
- evstwhe_2 = "10000331R4",
- evstwhox_3 = "10000334RR0R",
- evstwho_2 = "10000335R4",
- evstwwex_3 = "10000338RR0R",
- evstwwe_2 = "10000339R4",
- evstwwox_3 = "1000033cRR0R",
- evstwwo_2 = "1000033dR4",
- evmhessf_3 = "10000403RRR",
- evmhossf_3 = "10000407RRR",
- evmheumi_3 = "10000408RRR",
- evmhesmi_3 = "10000409RRR",
- evmhesmf_3 = "1000040bRRR",
- evmhoumi_3 = "1000040cRRR",
- evmhosmi_3 = "1000040dRRR",
- evmhosmf_3 = "1000040fRRR",
- evmhessfa_3 = "10000423RRR",
- evmhossfa_3 = "10000427RRR",
- evmheumia_3 = "10000428RRR",
- evmhesmia_3 = "10000429RRR",
- evmhesmfa_3 = "1000042bRRR",
- evmhoumia_3 = "1000042cRRR",
- evmhosmia_3 = "1000042dRRR",
- evmhosmfa_3 = "1000042fRRR",
- evmwhssf_3 = "10000447RRR",
- evmwlumi_3 = "10000448RRR",
- evmwhumi_3 = "1000044cRRR",
- evmwhsmi_3 = "1000044dRRR",
- evmwhsmf_3 = "1000044fRRR",
- evmwssf_3 = "10000453RRR",
- evmwumi_3 = "10000458RRR",
- evmwsmi_3 = "10000459RRR",
- evmwsmf_3 = "1000045bRRR",
- evmwhssfa_3 = "10000467RRR",
- evmwlumia_3 = "10000468RRR",
- evmwhumia_3 = "1000046cRRR",
- evmwhsmia_3 = "1000046dRRR",
- evmwhsmfa_3 = "1000046fRRR",
- evmwssfa_3 = "10000473RRR",
- evmwumia_3 = "10000478RRR",
- evmwsmia_3 = "10000479RRR",
- evmwsmfa_3 = "1000047bRRR",
- evmra_2 = "100004c4RR",
- evdivws_3 = "100004c6RRR",
- evdivwu_3 = "100004c7RRR",
- evmwssfaa_3 = "10000553RRR",
- evmwumiaa_3 = "10000558RRR",
- evmwsmiaa_3 = "10000559RRR",
- evmwsmfaa_3 = "1000055bRRR",
- evmwssfan_3 = "100005d3RRR",
- evmwumian_3 = "100005d8RRR",
- evmwsmian_3 = "100005d9RRR",
- evmwsmfan_3 = "100005dbRRR",
- evmergehilo_3 = "1000022eRRR",
- evmergelohi_3 = "1000022fRRR",
- evlhhesplatx_3 = "10000308RR0R",
- evlhhesplat_2 = "10000309R2",
- evlhhousplatx_3 = "1000030cRR0R",
- evlhhousplat_2 = "1000030dR2",
- evlhhossplatx_3 = "1000030eRR0R",
- evlhhossplat_2 = "1000030fR2",
- evlwwsplatx_3 = "10000318RR0R",
- evlwwsplat_2 = "10000319R4",
- evlwhsplatx_3 = "1000031cRR0R",
- evlwhsplat_2 = "1000031dR4",
- evaddusiaaw_2 = "100004c0RR",
- evaddssiaaw_2 = "100004c1RR",
- evsubfusiaaw_2 = "100004c2RR",
- evsubfssiaaw_2 = "100004c3RR",
- evaddumiaaw_2 = "100004c8RR",
- evaddsmiaaw_2 = "100004c9RR",
- evsubfumiaaw_2 = "100004caRR",
- evsubfsmiaaw_2 = "100004cbRR",
- evmheusiaaw_3 = "10000500RRR",
- evmhessiaaw_3 = "10000501RRR",
- evmhessfaaw_3 = "10000503RRR",
- evmhousiaaw_3 = "10000504RRR",
- evmhossiaaw_3 = "10000505RRR",
- evmhossfaaw_3 = "10000507RRR",
- evmheumiaaw_3 = "10000508RRR",
- evmhesmiaaw_3 = "10000509RRR",
- evmhesmfaaw_3 = "1000050bRRR",
- evmhoumiaaw_3 = "1000050cRRR",
- evmhosmiaaw_3 = "1000050dRRR",
- evmhosmfaaw_3 = "1000050fRRR",
- evmhegumiaa_3 = "10000528RRR",
- evmhegsmiaa_3 = "10000529RRR",
- evmhegsmfaa_3 = "1000052bRRR",
- evmhogumiaa_3 = "1000052cRRR",
- evmhogsmiaa_3 = "1000052dRRR",
- evmhogsmfaa_3 = "1000052fRRR",
- evmwlusiaaw_3 = "10000540RRR",
- evmwlssiaaw_3 = "10000541RRR",
- evmwlumiaaw_3 = "10000548RRR",
- evmwlsmiaaw_3 = "10000549RRR",
- evmheusianw_3 = "10000580RRR",
- evmhessianw_3 = "10000581RRR",
- evmhessfanw_3 = "10000583RRR",
- evmhousianw_3 = "10000584RRR",
- evmhossianw_3 = "10000585RRR",
- evmhossfanw_3 = "10000587RRR",
- evmheumianw_3 = "10000588RRR",
- evmhesmianw_3 = "10000589RRR",
- evmhesmfanw_3 = "1000058bRRR",
- evmhoumianw_3 = "1000058cRRR",
- evmhosmianw_3 = "1000058dRRR",
- evmhosmfanw_3 = "1000058fRRR",
- evmhegumian_3 = "100005a8RRR",
- evmhegsmian_3 = "100005a9RRR",
- evmhegsmfan_3 = "100005abRRR",
- evmhogumian_3 = "100005acRRR",
- evmhogsmian_3 = "100005adRRR",
- evmhogsmfan_3 = "100005afRRR",
- evmwlusianw_3 = "100005c0RRR",
- evmwlssianw_3 = "100005c1RRR",
- evmwlumianw_3 = "100005c8RRR",
- evmwlsmianw_3 = "100005c9RRR",
-
- -- NYI: Book E instructions.
-}
-
--- Add mnemonics for "." variants.
-do
- local t = {}
- for k,v in pairs(map_op) do
- if sub(v, -1) == "." then
- local v2 = sub(v, 1, 7)..char(byte(v, 8)+1)..sub(v, 9, -2)
- t[sub(k, 1, -3).."."..sub(k, -2)] = v2
- end
- end
- for k,v in pairs(t) do
- map_op[k] = v
- end
-end
-
--- Add more branch mnemonics.
-for cond,c in pairs(map_cond) do
- local b1 = "b"..cond
- local c1 = shl(band(c, 3), 16) + (c < 4 and 0x01000000 or 0)
- -- bX[l]
- map_op[b1.."_1"] = tohex(0x40800000 + c1).."K"
- map_op[b1.."y_1"] = tohex(0x40a00000 + c1).."K"
- map_op[b1.."l_1"] = tohex(0x40800001 + c1).."K"
- map_op[b1.."_2"] = tohex(0x40800000 + c1).."-XK"
- map_op[b1.."y_2"] = tohex(0x40a00000 + c1).."-XK"
- map_op[b1.."l_2"] = tohex(0x40800001 + c1).."-XK"
- -- bXlr[l]
- map_op[b1.."lr_0"] = tohex(0x4c800020 + c1)
- map_op[b1.."lrl_0"] = tohex(0x4c800021 + c1)
- map_op[b1.."ctr_0"] = tohex(0x4c800420 + c1)
- map_op[b1.."ctrl_0"] = tohex(0x4c800421 + c1)
- -- bXctr[l]
- map_op[b1.."lr_1"] = tohex(0x4c800020 + c1).."-X"
- map_op[b1.."lrl_1"] = tohex(0x4c800021 + c1).."-X"
- map_op[b1.."ctr_1"] = tohex(0x4c800420 + c1).."-X"
- map_op[b1.."ctrl_1"] = tohex(0x4c800421 + c1).."-X"
-end
-
-------------------------------------------------------------------------------
-
-local function parse_gpr(expr)
- local tname, ovreg = match(expr, "^([%w_]+):(r[1-3]?[0-9])$")
- local tp = map_type[tname or expr]
- if tp then
- local reg = ovreg or tp.reg
- if not reg then
- werror("type `"..(tname or expr).."' needs a register override")
- end
- expr = reg
- end
- local r = match(expr, "^r([1-3]?[0-9])$")
- if r then
- r = tonumber(r)
- if r <= 31 then return r, tp end
- end
- werror("bad register name `"..expr.."'")
-end
-
-local function parse_fpr(expr)
- local r = match(expr, "^f([1-3]?[0-9])$")
- if r then
- r = tonumber(r)
- if r <= 31 then return r end
- end
- werror("bad register name `"..expr.."'")
-end
-
-local function parse_cr(expr)
- local r = match(expr, "^cr([0-7])$")
- if r then return tonumber(r) end
- werror("bad condition register name `"..expr.."'")
-end
-
-local function parse_cond(expr)
- local r, cond = match(expr, "^4%*cr([0-7])%+(%w%w)$")
- if r then
- r = tonumber(r)
- local c = map_cond[cond]
- if c and c < 4 then return r*4+c end
- end
- werror("bad condition bit name `"..expr.."'")
-end
-
-local function parse_imm(imm, bits, shift, scale, signed)
- local n = tonumber(imm)
- if n then
- local m = sar(n, scale)
- if shl(m, scale) == n then
- if signed then
- local s = sar(m, bits-1)
- if s == 0 then return shl(m, shift)
- elseif s == -1 then return shl(m + shl(1, bits), shift) end
- else
- if sar(m, bits) == 0 then return shl(m, shift) end
- end
- end
- werror("out of range immediate `"..imm.."'")
- elseif match(imm, "^r([1-3]?[0-9])$") or
- match(imm, "^([%w_]+):(r[1-3]?[0-9])$") then
- werror("expected immediate operand, got register")
- else
- waction("IMM", (signed and 32768 or 0)+scale*1024+bits*32+shift, imm)
- return 0
- end
-end
-
-local function parse_shiftmask(imm, isshift)
- local n = tonumber(imm)
- if n then
- if shr(n, 6) == 0 then
- local lsb = band(imm, 31)
- local msb = imm - lsb
- return isshift and (shl(lsb, 11)+shr(msb, 4)) or (shl(lsb, 6)+msb)
- end
- werror("out of range immediate `"..imm.."'")
- elseif match(imm, "^r([1-3]?[0-9])$") or
- match(imm, "^([%w_]+):(r[1-3]?[0-9])$") then
- werror("expected immediate operand, got register")
- else
- werror("NYI: parameterized 64 bit shift/mask")
- end
-end
-
-local function parse_disp(disp)
- local imm, reg = match(disp, "^(.*)%(([%w_:]+)%)$")
- if imm then
- local r = parse_gpr(reg)
- if r == 0 then werror("cannot use r0 in displacement") end
- return shl(r, 16) + parse_imm(imm, 16, 0, 0, true)
- end
- local reg, tailr = match(disp, "^([%w_:]+)%s*(.*)$")
- if reg and tailr ~= "" then
- local r, tp = parse_gpr(reg)
- if r == 0 then werror("cannot use r0 in displacement") end
- if tp then
- waction("IMM", 32768+16*32, format(tp.ctypefmt, tailr))
- return shl(r, 16)
- end
- end
- werror("bad displacement `"..disp.."'")
-end
-
-local function parse_u5disp(disp, scale)
- local imm, reg = match(disp, "^(.*)%(([%w_:]+)%)$")
- if imm then
- local r = parse_gpr(reg)
- if r == 0 then werror("cannot use r0 in displacement") end
- return shl(r, 16) + parse_imm(imm, 5, 11, scale, false)
- end
- local reg, tailr = match(disp, "^([%w_:]+)%s*(.*)$")
- if reg and tailr ~= "" then
- local r, tp = parse_gpr(reg)
- if r == 0 then werror("cannot use r0 in displacement") end
- if tp then
- waction("IMM", scale*1024+5*32+11, format(tp.ctypefmt, tailr))
- return shl(r, 16)
- end
- end
- werror("bad displacement `"..disp.."'")
-end
-
-local function parse_label(label, def)
- local prefix = sub(label, 1, 2)
- -- =>label (pc label reference)
- if prefix == "=>" then
- return "PC", 0, sub(label, 3)
- end
- -- ->name (global label reference)
- if prefix == "->" then
- return "LG", map_global[sub(label, 3)]
- end
- if def then
- -- [1-9] (local label definition)
- if match(label, "^[1-9]$") then
- return "LG", 10+tonumber(label)
- end
- else
- -- [<>][1-9] (local label reference)
- local dir, lnum = match(label, "^([<>])([1-9])$")
- if dir then -- Fwd: 1-9, Bkwd: 11-19.
- return "LG", lnum + (dir == ">" and 0 or 10)
- end
- -- extern label (extern label reference)
- local extname = match(label, "^extern%s+(%S+)$")
- if extname then
- return "EXT", map_extern[extname]
- end
- end
- werror("bad label `"..label.."'")
-end
-
-------------------------------------------------------------------------------
-
--- Handle opcodes defined with template strings.
-map_op[".template__"] = function(params, template, nparams)
- if not params then return sub(template, 9) end
- local op = tonumber(sub(template, 1, 8), 16)
- local n, rs = 1, 26
-
- -- Limit number of section buffer positions used by a single dasm_put().
- -- A single opcode needs a maximum of 3 positions (rlwinm).
- if secpos+3 > maxsecpos then wflush() end
- local pos = wpos()
-
- -- Process each character.
- for p in gmatch(sub(template, 9), ".") do
- if p == "R" then
- rs = rs - 5; op = op + shl(parse_gpr(params[n]), rs); n = n + 1
- elseif p == "F" then
- rs = rs - 5; op = op + shl(parse_fpr(params[n]), rs); n = n + 1
- elseif p == "A" then
- rs = rs - 5; op = op + parse_imm(params[n], 5, rs, 0, false); n = n + 1
- elseif p == "S" then
- rs = rs - 5; op = op + parse_imm(params[n], 5, rs, 0, true); n = n + 1
- elseif p == "I" then
- op = op + parse_imm(params[n], 16, 0, 0, true); n = n + 1
- elseif p == "U" then
- op = op + parse_imm(params[n], 16, 0, 0, false); n = n + 1
- elseif p == "D" then
- op = op + parse_disp(params[n]); n = n + 1
- elseif p == "2" then
- op = op + parse_u5disp(params[n], 1); n = n + 1
- elseif p == "4" then
- op = op + parse_u5disp(params[n], 2); n = n + 1
- elseif p == "8" then
- op = op + parse_u5disp(params[n], 3); n = n + 1
- elseif p == "C" then
- rs = rs - 5; op = op + shl(parse_cond(params[n]), rs); n = n + 1
- elseif p == "X" then
- rs = rs - 5; op = op + shl(parse_cr(params[n]), rs+2); n = n + 1
- elseif p == "W" then
- op = op + parse_cr(params[n]); n = n + 1
- elseif p == "G" then
- op = op + parse_imm(params[n], 8, 12, 0, false); n = n + 1
- elseif p == "H" then
- op = op + parse_shiftmask(params[n], true); n = n + 1
- elseif p == "M" then
- op = op + parse_shiftmask(params[n], false); n = n + 1
- elseif p == "J" or p == "K" then
- local mode, n, s = parse_label(params[n], false)
- if p == "K" then n = n + 2048 end
- waction("REL_"..mode, n, s, 1)
- n = n + 1
- elseif p == "0" then
- if band(shr(op, rs), 31) == 0 then werror("cannot use r0") end
- elseif p == "=" or p == "%" then
- local t = band(shr(op, p == "%" and rs+5 or rs), 31)
- rs = rs - 5
- op = op + shl(t, rs)
- elseif p == "~" then
- local mm = shl(31, rs)
- local lo = band(op, mm)
- local hi = band(op, shl(mm, 5))
- op = op - lo - hi + shl(lo, 5) + shr(hi, 5)
- elseif p == "-" then
- rs = rs - 5
- elseif p == "." then
- -- Ignored.
- else
- assert(false)
- end
- end
- wputpos(pos, op)
-end
-
-------------------------------------------------------------------------------
-
--- Pseudo-opcode to mark the position where the action list is to be emitted.
-map_op[".actionlist_1"] = function(params)
- if not params then return "cvar" end
- local name = params[1] -- No syntax check. You get to keep the pieces.
- wline(function(out) writeactions(out, name) end)
-end
-
--- Pseudo-opcode to mark the position where the global enum is to be emitted.
-map_op[".globals_1"] = function(params)
- if not params then return "prefix" end
- local prefix = params[1] -- No syntax check. You get to keep the pieces.
- wline(function(out) writeglobals(out, prefix) end)
-end
-
--- Pseudo-opcode to mark the position where the global names are to be emitted.
-map_op[".globalnames_1"] = function(params)
- if not params then return "cvar" end
- local name = params[1] -- No syntax check. You get to keep the pieces.
- wline(function(out) writeglobalnames(out, name) end)
-end
-
--- Pseudo-opcode to mark the position where the extern names are to be emitted.
-map_op[".externnames_1"] = function(params)
- if not params then return "cvar" end
- local name = params[1] -- No syntax check. You get to keep the pieces.
- wline(function(out) writeexternnames(out, name) end)
-end
-
-------------------------------------------------------------------------------
-
--- Label pseudo-opcode (converted from trailing colon form).
-map_op[".label_1"] = function(params)
- if not params then return "[1-9] | ->global | =>pcexpr" end
- if secpos+1 > maxsecpos then wflush() end
- local mode, n, s = parse_label(params[1], true)
- if mode == "EXT" then werror("bad label definition") end
- waction("LABEL_"..mode, n, s, 1)
-end
-
-------------------------------------------------------------------------------
-
--- Pseudo-opcodes for data storage.
-map_op[".long_*"] = function(params)
- if not params then return "imm..." end
- for _,p in ipairs(params) do
- local n = tonumber(p)
- if not n then werror("bad immediate `"..p.."'") end
- if n < 0 then n = n + 2^32 end
- wputw(n)
- if secpos+2 > maxsecpos then wflush() end
- end
-end
-
--- Alignment pseudo-opcode.
-map_op[".align_1"] = function(params)
- if not params then return "numpow2" end
- if secpos+1 > maxsecpos then wflush() end
- local align = tonumber(params[1])
- if align then
- local x = align
- -- Must be a power of 2 in the range (2 ... 256).
- for i=1,8 do
- x = x / 2
- if x == 1 then
- waction("ALIGN", align-1, nil, 1) -- Action byte is 2**n-1.
- return
- end
- end
- end
- werror("bad alignment")
-end
-
-------------------------------------------------------------------------------
-
--- Pseudo-opcode for (primitive) type definitions (map to C types).
-map_op[".type_3"] = function(params, nparams)
- if not params then
- return nparams == 2 and "name, ctype" or "name, ctype, reg"
- end
- local name, ctype, reg = params[1], params[2], params[3]
- if not match(name, "^[%a_][%w_]*$") then
- werror("bad type name `"..name.."'")
- end
- local tp = map_type[name]
- if tp then
- werror("duplicate type `"..name.."'")
- end
- -- Add #type to defines. A bit unclean to put it in map_archdef.
- map_archdef["#"..name] = "sizeof("..ctype..")"
- -- Add new type and emit shortcut define.
- local num = ctypenum + 1
- map_type[name] = {
- ctype = ctype,
- ctypefmt = format("Dt%X(%%s)", num),
- reg = reg,
- }
- wline(format("#define Dt%X(_V) (int)(ptrdiff_t)&(((%s *)0)_V)", num, ctype))
- ctypenum = num
-end
-map_op[".type_2"] = map_op[".type_3"]
-
--- Dump type definitions.
-local function dumptypes(out, lvl)
- local t = {}
- for name in pairs(map_type) do t[#t+1] = name end
- sort(t)
- out:write("Type definitions:\n")
- for _,name in ipairs(t) do
- local tp = map_type[name]
- local reg = tp.reg or ""
- out:write(format(" %-20s %-20s %s\n", name, tp.ctype, reg))
- end
- out:write("\n")
-end
-
-------------------------------------------------------------------------------
-
--- Set the current section.
-function _M.section(num)
- waction("SECTION", num)
- wflush(true) -- SECTION is a terminal action.
-end
-
-------------------------------------------------------------------------------
-
--- Dump architecture description.
-function _M.dumparch(out)
- out:write(format("DynASM %s version %s, released %s\n\n",
- _info.arch, _info.version, _info.release))
- dumpactions(out)
-end
-
--- Dump all user defined elements.
-function _M.dumpdef(out, lvl)
- dumptypes(out, lvl)
- dumpglobals(out, lvl)
- dumpexterns(out, lvl)
-end
-
-------------------------------------------------------------------------------
-
--- Pass callbacks from/to the DynASM core.
-function _M.passcb(wl, we, wf, ww)
- wline, werror, wfatal, wwarn = wl, we, wf, ww
- return wflush
-end
-
--- Setup the arch-specific module.
-function _M.setup(arch, opt)
- g_arch, g_opt = arch, opt
-end
-
--- Merge the core maps and the arch-specific maps.
-function _M.mergemaps(map_coreop, map_def)
- setmetatable(map_op, { __index = map_coreop })
- setmetatable(map_def, { __index = map_archdef })
- return map_op, map_def
-end
-
-return _M
-
-------------------------------------------------------------------------------
-
diff --git a/core/src/luajit/dynasm/dasm_proto.h b/core/src/luajit/dynasm/dasm_proto.h
deleted file mode 100644
index a8bc6fd28..000000000
--- a/core/src/luajit/dynasm/dasm_proto.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
-** DynASM encoding engine prototypes.
-** Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-** Released under the MIT license. See dynasm.lua for full copyright notice.
-*/
-
-#ifndef _DASM_PROTO_H
-#define _DASM_PROTO_H
-
-#include <stddef.h>
-#include <stdarg.h>
-
-#define DASM_IDENT "DynASM 1.3.0"
-#define DASM_VERSION 10300 /* 1.3.0 */
-
-#ifndef Dst_DECL
-#define Dst_DECL dasm_State **Dst
-#endif
-
-#ifndef Dst_REF
-#define Dst_REF (*Dst)
-#endif
-
-#ifndef DASM_FDEF
-#define DASM_FDEF extern
-#endif
-
-#ifndef DASM_M_GROW
-#define DASM_M_GROW(ctx, t, p, sz, need) \
- do { \
- size_t _sz = (sz), _need = (need); \
- if (_sz < _need) { \
- if (_sz < 16) _sz = 16; \
- while (_sz < _need) _sz += _sz; \
- (p) = (t *)realloc((p), _sz); \
- if ((p) == NULL) exit(1); \
- (sz) = _sz; \
- } \
- } while(0)
-#endif
-
-#ifndef DASM_M_FREE
-#define DASM_M_FREE(ctx, p, sz) free(p)
-#endif
-
-/* Internal DynASM encoder state. */
-typedef struct dasm_State dasm_State;
-
-
-/* Initialize and free DynASM state. */
-DASM_FDEF void dasm_init(Dst_DECL, int maxsection);
-DASM_FDEF void dasm_free(Dst_DECL);
-
-/* Setup global array. Must be called before dasm_setup(). */
-DASM_FDEF void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl);
-
-/* Grow PC label array. Can be called after dasm_setup(), too. */
-DASM_FDEF void dasm_growpc(Dst_DECL, unsigned int maxpc);
-
-/* Setup encoder. */
-DASM_FDEF void dasm_setup(Dst_DECL, const void *actionlist);
-
-/* Feed encoder with actions. Calls are generated by pre-processor. */
-DASM_FDEF void dasm_put(Dst_DECL, int start, ...);
-
-/* Link sections and return the resulting size. */
-DASM_FDEF int dasm_link(Dst_DECL, size_t *szp);
-
-/* Encode sections into buffer. */
-DASM_FDEF int dasm_encode(Dst_DECL, void *buffer);
-
-/* Get PC label offset. */
-DASM_FDEF int dasm_getpclabel(Dst_DECL, unsigned int pc);
-
-#ifdef DASM_CHECKS
-/* Optional sanity checker to call between isolated encoding steps. */
-DASM_FDEF int dasm_checkstep(Dst_DECL, int secmatch);
-#else
-#define dasm_checkstep(a, b) 0
-#endif
-
-
-#endif /* _DASM_PROTO_H */
diff --git a/core/src/luajit/dynasm/dasm_x64.lua b/core/src/luajit/dynasm/dasm_x64.lua
deleted file mode 100644
index b1b62022f..000000000
--- a/core/src/luajit/dynasm/dasm_x64.lua
+++ /dev/null
@@ -1,12 +0,0 @@
-------------------------------------------------------------------------------
--- DynASM x64 module.
---
--- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
--- See dynasm.lua for full copyright notice.
-------------------------------------------------------------------------------
--- This module just sets 64 bit mode for the combined x86/x64 module.
--- All the interesting stuff is there.
-------------------------------------------------------------------------------
-
-x64 = true -- Using a global is an ugly, but effective solution.
-return require("dasm_x86")
diff --git a/core/src/luajit/dynasm/dasm_x86.h b/core/src/luajit/dynasm/dasm_x86.h
deleted file mode 100644
index 652e8c99b..000000000
--- a/core/src/luajit/dynasm/dasm_x86.h
+++ /dev/null
@@ -1,471 +0,0 @@
-/*
-** DynASM x86 encoding engine.
-** Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-** Released under the MIT license. See dynasm.lua for full copyright notice.
-*/
-
-#include <stddef.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdlib.h>
-
-#define DASM_ARCH "x86"
-
-#ifndef DASM_EXTERN
-#define DASM_EXTERN(a,b,c,d) 0
-#endif
-
-/* Action definitions. DASM_STOP must be 255. */
-enum {
- DASM_DISP = 233,
- DASM_IMM_S, DASM_IMM_B, DASM_IMM_W, DASM_IMM_D, DASM_IMM_WB, DASM_IMM_DB,
- DASM_VREG, DASM_SPACE, DASM_SETLABEL, DASM_REL_A, DASM_REL_LG, DASM_REL_PC,
- DASM_IMM_LG, DASM_IMM_PC, DASM_LABEL_LG, DASM_LABEL_PC, DASM_ALIGN,
- DASM_EXTERN, DASM_ESC, DASM_MARK, DASM_SECTION, DASM_STOP
-};
-
-/* Maximum number of section buffer positions for a single dasm_put() call. */
-#define DASM_MAXSECPOS 25
-
-/* DynASM encoder status codes. Action list offset or number are or'ed in. */
-#define DASM_S_OK 0x00000000
-#define DASM_S_NOMEM 0x01000000
-#define DASM_S_PHASE 0x02000000
-#define DASM_S_MATCH_SEC 0x03000000
-#define DASM_S_RANGE_I 0x11000000
-#define DASM_S_RANGE_SEC 0x12000000
-#define DASM_S_RANGE_LG 0x13000000
-#define DASM_S_RANGE_PC 0x14000000
-#define DASM_S_RANGE_VREG 0x15000000
-#define DASM_S_UNDEF_L 0x21000000
-#define DASM_S_UNDEF_PC 0x22000000
-
-/* Macros to convert positions (8 bit section + 24 bit index). */
-#define DASM_POS2IDX(pos) ((pos)&0x00ffffff)
-#define DASM_POS2BIAS(pos) ((pos)&0xff000000)
-#define DASM_SEC2POS(sec) ((sec)<<24)
-#define DASM_POS2SEC(pos) ((pos)>>24)
-#define DASM_POS2PTR(D, pos) (D->sections[DASM_POS2SEC(pos)].rbuf + (pos))
-
-/* Action list type. */
-typedef const unsigned char *dasm_ActList;
-
-/* Per-section structure. */
-typedef struct dasm_Section {
- int *rbuf; /* Biased buffer pointer (negative section bias). */
- int *buf; /* True buffer pointer. */
- size_t bsize; /* Buffer size in bytes. */
- int pos; /* Biased buffer position. */
- int epos; /* End of biased buffer position - max single put. */
- int ofs; /* Byte offset into section. */
-} dasm_Section;
-
-/* Core structure holding the DynASM encoding state. */
-struct dasm_State {
- size_t psize; /* Allocated size of this structure. */
- dasm_ActList actionlist; /* Current actionlist pointer. */
- int *lglabels; /* Local/global chain/pos ptrs. */
- size_t lgsize;
- int *pclabels; /* PC label chains/pos ptrs. */
- size_t pcsize;
- void **globals; /* Array of globals (bias -10). */
- dasm_Section *section; /* Pointer to active section. */
- size_t codesize; /* Total size of all code sections. */
- int maxsection; /* 0 <= sectionidx < maxsection. */
- int status; /* Status code. */
- dasm_Section sections[1]; /* All sections. Alloc-extended. */
-};
-
-/* The size of the core structure depends on the max. number of sections. */
-#define DASM_PSZ(ms) (sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))
-
-
-/* Initialize DynASM state. */
-void dasm_init(Dst_DECL, int maxsection)
-{
- dasm_State *D;
- size_t psz = 0;
- int i;
- Dst_REF = NULL;
- DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
- D = Dst_REF;
- D->psize = psz;
- D->lglabels = NULL;
- D->lgsize = 0;
- D->pclabels = NULL;
- D->pcsize = 0;
- D->globals = NULL;
- D->maxsection = maxsection;
- for (i = 0; i < maxsection; i++) {
- D->sections[i].buf = NULL; /* Need this for pass3. */
- D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);
- D->sections[i].bsize = 0;
- D->sections[i].epos = 0; /* Wrong, but is recalculated after resize. */
- }
-}
-
-/* Free DynASM state. */
-void dasm_free(Dst_DECL)
-{
- dasm_State *D = Dst_REF;
- int i;
- for (i = 0; i < D->maxsection; i++)
- if (D->sections[i].buf)
- DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);
- if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);
- if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);
- DASM_M_FREE(Dst, D, D->psize);
-}
-
-/* Setup global label array. Must be called before dasm_setup(). */
-void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
-{
- dasm_State *D = Dst_REF;
- D->globals = gl - 10; /* Negative bias to compensate for locals. */
- DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
-}
-
-/* Grow PC label array. Can be called after dasm_setup(), too. */
-void dasm_growpc(Dst_DECL, unsigned int maxpc)
-{
- dasm_State *D = Dst_REF;
- size_t osz = D->pcsize;
- DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));
- memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);
-}
-
-/* Setup encoder. */
-void dasm_setup(Dst_DECL, const void *actionlist)
-{
- dasm_State *D = Dst_REF;
- int i;
- D->actionlist = (dasm_ActList)actionlist;
- D->status = DASM_S_OK;
- D->section = &D->sections[0];
- memset((void *)D->lglabels, 0, D->lgsize);
- if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
- for (i = 0; i < D->maxsection; i++) {
- D->sections[i].pos = DASM_SEC2POS(i);
- D->sections[i].ofs = 0;
- }
-}
-
-
-#ifdef DASM_CHECKS
-#define CK(x, st) \
- do { if (!(x)) { \
- D->status = DASM_S_##st|(int)(p-D->actionlist-1); return; } } while (0)
-#define CKPL(kind, st) \
- do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \
- D->status=DASM_S_RANGE_##st|(int)(p-D->actionlist-1); return; } } while (0)
-#else
-#define CK(x, st) ((void)0)
-#define CKPL(kind, st) ((void)0)
-#endif
-
-/* Pass 1: Store actions and args, link branches/labels, estimate offsets. */
-void dasm_put(Dst_DECL, int start, ...)
-{
- va_list ap;
- dasm_State *D = Dst_REF;
- dasm_ActList p = D->actionlist + start;
- dasm_Section *sec = D->section;
- int pos = sec->pos, ofs = sec->ofs, mrm = 4;
- int *b;
-
- if (pos >= sec->epos) {
- DASM_M_GROW(Dst, int, sec->buf, sec->bsize,
- sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));
- sec->rbuf = sec->buf - DASM_POS2BIAS(pos);
- sec->epos = (int)sec->bsize/sizeof(int) - DASM_MAXSECPOS+DASM_POS2BIAS(pos);
- }
-
- b = sec->rbuf;
- b[pos++] = start;
-
- va_start(ap, start);
- while (1) {
- int action = *p++;
- if (action < DASM_DISP) {
- ofs++;
- } else if (action <= DASM_REL_A) {
- int n = va_arg(ap, int);
- b[pos++] = n;
- switch (action) {
- case DASM_DISP:
- if (n == 0) { if ((mrm&7) == 4) mrm = p[-2]; if ((mrm&7) != 5) break; }
- case DASM_IMM_DB: if (((n+128)&-256) == 0) goto ob;
- case DASM_REL_A: /* Assumes ptrdiff_t is int. !x64 */
- case DASM_IMM_D: ofs += 4; break;
- case DASM_IMM_S: CK(((n+128)&-256) == 0, RANGE_I); goto ob;
- case DASM_IMM_B: CK((n&-256) == 0, RANGE_I); ob: ofs++; break;
- case DASM_IMM_WB: if (((n+128)&-256) == 0) goto ob;
- case DASM_IMM_W: CK((n&-65536) == 0, RANGE_I); ofs += 2; break;
- case DASM_SPACE: p++; ofs += n; break;
- case DASM_SETLABEL: b[pos-2] = -0x40000000; break; /* Neg. label ofs. */
- case DASM_VREG: CK((n&-8) == 0 && (n != 4 || (*p&1) == 0), RANGE_VREG);
- if (*p++ == 1 && *p == DASM_DISP) mrm = n; continue;
- }
- mrm = 4;
- } else {
- int *pl, n;
- switch (action) {
- case DASM_REL_LG:
- case DASM_IMM_LG:
- n = *p++; pl = D->lglabels + n;
- /* Bkwd rel or global. */
- if (n <= 246) { CK(n>=10||*pl<0, RANGE_LG); CKPL(lg, LG); goto putrel; }
- pl -= 246; n = *pl;
- if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
- goto linkrel;
- case DASM_REL_PC:
- case DASM_IMM_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);
- putrel:
- n = *pl;
- if (n < 0) { /* Label exists. Get label pos and store it. */
- b[pos] = -n;
- } else {
- linkrel:
- b[pos] = n; /* Else link to rel chain, anchored at label. */
- *pl = pos;
- }
- pos++;
- ofs += 4; /* Maximum offset needed. */
- if (action == DASM_REL_LG || action == DASM_REL_PC)
- b[pos++] = ofs; /* Store pass1 offset estimate. */
- break;
- case DASM_LABEL_LG: pl = D->lglabels + *p++; CKPL(lg, LG); goto putlabel;
- case DASM_LABEL_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);
- putlabel:
- n = *pl; /* n > 0: Collapse rel chain and replace with label pos. */
- while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos; }
- *pl = -pos; /* Label exists now. */
- b[pos++] = ofs; /* Store pass1 offset estimate. */
- break;
- case DASM_ALIGN:
- ofs += *p++; /* Maximum alignment needed (arg is 2**n-1). */
- b[pos++] = ofs; /* Store pass1 offset estimate. */
- break;
- case DASM_EXTERN: p += 2; ofs += 4; break;
- case DASM_ESC: p++; ofs++; break;
- case DASM_MARK: mrm = p[-2]; break;
- case DASM_SECTION:
- n = *p; CK(n < D->maxsection, RANGE_SEC); D->section = &D->sections[n];
- case DASM_STOP: goto stop;
- }
- }
- }
-stop:
- va_end(ap);
- sec->pos = pos;
- sec->ofs = ofs;
-}
-#undef CK
-
-/* Pass 2: Link sections, shrink branches/aligns, fix label offsets. */
-int dasm_link(Dst_DECL, size_t *szp)
-{
- dasm_State *D = Dst_REF;
- int secnum;
- int ofs = 0;
-
-#ifdef DASM_CHECKS
- *szp = 0;
- if (D->status != DASM_S_OK) return D->status;
- {
- int pc;
- for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)
- if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;
- }
-#endif
-
- { /* Handle globals not defined in this translation unit. */
- int idx;
- for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {
- int n = D->lglabels[idx];
- /* Undefined label: Collapse rel chain and replace with marker (< 0). */
- while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
- }
- }
-
- /* Combine all code sections. No support for data sections (yet). */
- for (secnum = 0; secnum < D->maxsection; secnum++) {
- dasm_Section *sec = D->sections + secnum;
- int *b = sec->rbuf;
- int pos = DASM_SEC2POS(secnum);
- int lastpos = sec->pos;
-
- while (pos != lastpos) {
- dasm_ActList p = D->actionlist + b[pos++];
- while (1) {
- int op, action = *p++;
- switch (action) {
- case DASM_REL_LG: p++; op = p[-3]; goto rel_pc;
- case DASM_REL_PC: op = p[-2]; rel_pc: {
- int shrink = op == 0xe9 ? 3 : ((op&0xf0) == 0x80 ? 4 : 0);
- if (shrink) { /* Shrinkable branch opcode? */
- int lofs, lpos = b[pos];
- if (lpos < 0) goto noshrink; /* Ext global? */
- lofs = *DASM_POS2PTR(D, lpos);
- if (lpos > pos) { /* Fwd label: add cumulative section offsets. */
- int i;
- for (i = secnum; i < DASM_POS2SEC(lpos); i++)
- lofs += D->sections[i].ofs;
- } else {
- lofs -= ofs; /* Bkwd label: unfix offset. */
- }
- lofs -= b[pos+1]; /* Short branch ok? */
- if (lofs >= -128-shrink && lofs <= 127) ofs -= shrink; /* Yes. */
- else { noshrink: shrink = 0; } /* No, cannot shrink op. */
- }
- b[pos+1] = shrink;
- pos += 2;
- break;
- }
- case DASM_SPACE: case DASM_IMM_LG: case DASM_VREG: p++;
- case DASM_DISP: case DASM_IMM_S: case DASM_IMM_B: case DASM_IMM_W:
- case DASM_IMM_D: case DASM_IMM_WB: case DASM_IMM_DB:
- case DASM_SETLABEL: case DASM_REL_A: case DASM_IMM_PC: pos++; break;
- case DASM_LABEL_LG: p++;
- case DASM_LABEL_PC: b[pos++] += ofs; break; /* Fix label offset. */
- case DASM_ALIGN: ofs -= (b[pos++]+ofs)&*p++; break; /* Adjust ofs. */
- case DASM_EXTERN: p += 2; break;
- case DASM_ESC: p++; break;
- case DASM_MARK: break;
- case DASM_SECTION: case DASM_STOP: goto stop;
- }
- }
- stop: (void)0;
- }
- ofs += sec->ofs; /* Next section starts right after current section. */
- }
-
- D->codesize = ofs; /* Total size of all code sections */
- *szp = ofs;
- return DASM_S_OK;
-}
-
-#define dasmb(x) *cp++ = (unsigned char)(x)
-#ifndef DASM_ALIGNED_WRITES
-#define dasmw(x) \
- do { *((unsigned short *)cp) = (unsigned short)(x); cp+=2; } while (0)
-#define dasmd(x) \
- do { *((unsigned int *)cp) = (unsigned int)(x); cp+=4; } while (0)
-#else
-#define dasmw(x) do { dasmb(x); dasmb((x)>>8); } while (0)
-#define dasmd(x) do { dasmw(x); dasmw((x)>>16); } while (0)
-#endif
-
-/* Pass 3: Encode sections. */
-int dasm_encode(Dst_DECL, void *buffer)
-{
- dasm_State *D = Dst_REF;
- unsigned char *base = (unsigned char *)buffer;
- unsigned char *cp = base;
- int secnum;
-
- /* Encode all code sections. No support for data sections (yet). */
- for (secnum = 0; secnum < D->maxsection; secnum++) {
- dasm_Section *sec = D->sections + secnum;
- int *b = sec->buf;
- int *endb = sec->rbuf + sec->pos;
-
- while (b != endb) {
- dasm_ActList p = D->actionlist + *b++;
- unsigned char *mark = NULL;
- while (1) {
- int action = *p++;
- int n = (action >= DASM_DISP && action <= DASM_ALIGN) ? *b++ : 0;
- switch (action) {
- case DASM_DISP: if (!mark) mark = cp; {
- unsigned char *mm = mark;
- if (*p != DASM_IMM_DB && *p != DASM_IMM_WB) mark = NULL;
- if (n == 0) { int mrm = mm[-1]&7; if (mrm == 4) mrm = mm[0]&7;
- if (mrm != 5) { mm[-1] -= 0x80; break; } }
- if (((n+128) & -256) != 0) goto wd; else mm[-1] -= 0x40;
- }
- case DASM_IMM_S: case DASM_IMM_B: wb: dasmb(n); break;
- case DASM_IMM_DB: if (((n+128)&-256) == 0) {
- db: if (!mark) mark = cp; mark[-2] += 2; mark = NULL; goto wb;
- } else mark = NULL;
- case DASM_IMM_D: wd: dasmd(n); break;
- case DASM_IMM_WB: if (((n+128)&-256) == 0) goto db; else mark = NULL;
- case DASM_IMM_W: dasmw(n); break;
- case DASM_VREG: { int t = *p++; if (t >= 2) n<<=3; cp[-1] |= n; break; }
- case DASM_REL_LG: p++; if (n >= 0) goto rel_pc;
- b++; n = (int)(ptrdiff_t)D->globals[-n];
- case DASM_REL_A: rel_a: n -= (int)(ptrdiff_t)(cp+4); goto wd; /* !x64 */
- case DASM_REL_PC: rel_pc: {
- int shrink = *b++;
- int *pb = DASM_POS2PTR(D, n); if (*pb < 0) { n = pb[1]; goto rel_a; }
- n = *pb - ((int)(cp-base) + 4-shrink);
- if (shrink == 0) goto wd;
- if (shrink == 4) { cp--; cp[-1] = *cp-0x10; } else cp[-1] = 0xeb;
- goto wb;
- }
- case DASM_IMM_LG:
- p++; if (n < 0) { n = (int)(ptrdiff_t)D->globals[-n]; goto wd; }
- case DASM_IMM_PC: {
- int *pb = DASM_POS2PTR(D, n);
- n = *pb < 0 ? pb[1] : (*pb + (int)(ptrdiff_t)base);
- goto wd;
- }
- case DASM_LABEL_LG: {
- int idx = *p++;
- if (idx >= 10)
- D->globals[idx] = (void *)(base + (*p == DASM_SETLABEL ? *b : n));
- break;
- }
- case DASM_LABEL_PC: case DASM_SETLABEL: break;
- case DASM_SPACE: { int fill = *p++; while (n--) *cp++ = fill; break; }
- case DASM_ALIGN:
- n = *p++;
- while (((cp-base) & n)) *cp++ = 0x90; /* nop */
- break;
- case DASM_EXTERN: n = DASM_EXTERN(Dst, cp, p[1], *p); p += 2; goto wd;
- case DASM_MARK: mark = cp; break;
- case DASM_ESC: action = *p++;
- default: *cp++ = action; break;
- case DASM_SECTION: case DASM_STOP: goto stop;
- }
- }
- stop: (void)0;
- }
- }
-
- if (base + D->codesize != cp) /* Check for phase errors. */
- return DASM_S_PHASE;
- return DASM_S_OK;
-}
-
-/* Get PC label offset. */
-int dasm_getpclabel(Dst_DECL, unsigned int pc)
-{
- dasm_State *D = Dst_REF;
- if (pc*sizeof(int) < D->pcsize) {
- int pos = D->pclabels[pc];
- if (pos < 0) return *DASM_POS2PTR(D, -pos);
- if (pos > 0) return -1; /* Undefined. */
- }
- return -2; /* Unused or out of range. */
-}
-
-#ifdef DASM_CHECKS
-/* Optional sanity checker to call between isolated encoding steps. */
-int dasm_checkstep(Dst_DECL, int secmatch)
-{
- dasm_State *D = Dst_REF;
- if (D->status == DASM_S_OK) {
- int i;
- for (i = 1; i <= 9; i++) {
- if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_L|i; break; }
- D->lglabels[i] = 0;
- }
- }
- if (D->status == DASM_S_OK && secmatch >= 0 &&
- D->section != &D->sections[secmatch])
- D->status = DASM_S_MATCH_SEC|(int)(D->section-D->sections);
- return D->status;
-}
-#endif
-
diff --git a/core/src/luajit/dynasm/dasm_x86.lua b/core/src/luajit/dynasm/dasm_x86.lua
deleted file mode 100644
index 7ca061d22..000000000
--- a/core/src/luajit/dynasm/dasm_x86.lua
+++ /dev/null
@@ -1,1945 +0,0 @@
-------------------------------------------------------------------------------
--- DynASM x86/x64 module.
---
--- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
--- See dynasm.lua for full copyright notice.
-------------------------------------------------------------------------------
-
-local x64 = x64
-
--- Module information:
-local _info = {
- arch = x64 and "x64" or "x86",
- description = "DynASM x86/x64 module",
- version = "1.3.0",
- vernum = 10300,
- release = "2011-05-05",
- author = "Mike Pall",
- license = "MIT",
-}
-
--- Exported glue functions for the arch-specific module.
-local _M = { _info = _info }
-
--- Cache library functions.
-local type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs
-local assert, unpack, setmetatable = assert, unpack or table.unpack, setmetatable
-local _s = string
-local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
-local find, match, gmatch, gsub = _s.find, _s.match, _s.gmatch, _s.gsub
-local concat, sort = table.concat, table.sort
-local bit = bit or require("bit")
-local band, shl, shr = bit.band, bit.lshift, bit.rshift
-
--- Inherited tables and callbacks.
-local g_opt, g_arch
-local wline, werror, wfatal, wwarn
-
--- Action name list.
--- CHECK: Keep this in sync with the C code!
-local action_names = {
- -- int arg, 1 buffer pos:
- "DISP", "IMM_S", "IMM_B", "IMM_W", "IMM_D", "IMM_WB", "IMM_DB",
- -- action arg (1 byte), int arg, 1 buffer pos (reg/num):
- "VREG", "SPACE", -- !x64: VREG support NYI.
- -- ptrdiff_t arg, 1 buffer pos (address): !x64
- "SETLABEL", "REL_A",
- -- action arg (1 byte) or int arg, 2 buffer pos (link, offset):
- "REL_LG", "REL_PC",
- -- action arg (1 byte) or int arg, 1 buffer pos (link):
- "IMM_LG", "IMM_PC",
- -- action arg (1 byte) or int arg, 1 buffer pos (offset):
- "LABEL_LG", "LABEL_PC",
- -- action arg (1 byte), 1 buffer pos (offset):
- "ALIGN",
- -- action args (2 bytes), no buffer pos.
- "EXTERN",
- -- action arg (1 byte), no buffer pos.
- "ESC",
- -- no action arg, no buffer pos.
- "MARK",
- -- action arg (1 byte), no buffer pos, terminal action:
- "SECTION",
- -- no args, no buffer pos, terminal action:
- "STOP"
-}
-
--- Maximum number of section buffer positions for dasm_put().
--- CHECK: Keep this in sync with the C code!
-local maxsecpos = 25 -- Keep this low, to avoid excessively long C lines.
-
--- Action name -> action number (dynamically generated below).
-local map_action = {}
--- First action number. Everything below does not need to be escaped.
-local actfirst = 256-#action_names
-
--- Action list buffer and string (only used to remove dupes).
-local actlist = {}
-local actstr = ""
-
--- Argument list for next dasm_put(). Start with offset 0 into action list.
-local actargs = { 0 }
-
--- Current number of section buffer positions for dasm_put().
-local secpos = 1
-
-------------------------------------------------------------------------------
-
--- Compute action numbers for action names.
-for n,name in ipairs(action_names) do
- local num = actfirst + n - 1
- map_action[name] = num
-end
-
--- Dump action names and numbers.
-local function dumpactions(out)
- out:write("DynASM encoding engine action codes:\n")
- for n,name in ipairs(action_names) do
- local num = map_action[name]
- out:write(format(" %-10s %02X %d\n", name, num, num))
- end
- out:write("\n")
-end
-
--- Write action list buffer as a huge static C array.
-local function writeactions(out, name)
- local nn = #actlist
- local last = actlist[nn] or 255
- actlist[nn] = nil -- Remove last byte.
- if nn == 0 then nn = 1 end
- out:write("static const unsigned char ", name, "[", nn, "] = {\n")
- local s = " "
- for n,b in ipairs(actlist) do
- s = s..b..","
- if #s >= 75 then
- assert(out:write(s, "\n"))
- s = " "
- end
- end
- out:write(s, last, "\n};\n\n") -- Add last byte back.
-end
-
-------------------------------------------------------------------------------
-
--- Add byte to action list.
-local function wputxb(n)
- assert(n >= 0 and n <= 255 and n % 1 == 0, "byte out of range")
- actlist[#actlist+1] = n
-end
-
--- Add action to list with optional arg. Advance buffer pos, too.
-local function waction(action, a, num)
- wputxb(assert(map_action[action], "bad action name `"..action.."'"))
- if a then actargs[#actargs+1] = a end
- if a or num then secpos = secpos + (num or 1) end
-end
-
--- Add call to embedded DynASM C code.
-local function wcall(func, args)
- wline(format("dasm_%s(Dst, %s);", func, concat(args, ", ")), true)
-end
-
--- Delete duplicate action list chunks. A tad slow, but so what.
-local function dedupechunk(offset)
- local al, as = actlist, actstr
- local chunk = char(unpack(al, offset+1, #al))
- local orig = find(as, chunk, 1, true)
- if orig then
- actargs[1] = orig-1 -- Replace with original offset.
- for i=offset+1,#al do al[i] = nil end -- Kill dupe.
- else
- actstr = as..chunk
- end
-end
-
--- Flush action list (intervening C code or buffer pos overflow).
-local function wflush(term)
- local offset = actargs[1]
- if #actlist == offset then return end -- Nothing to flush.
- if not term then waction("STOP") end -- Terminate action list.
- dedupechunk(offset)
- wcall("put", actargs) -- Add call to dasm_put().
- actargs = { #actlist } -- Actionlist offset is 1st arg to next dasm_put().
- secpos = 1 -- The actionlist offset occupies a buffer position, too.
-end
-
--- Put escaped byte.
-local function wputb(n)
- if n >= actfirst then waction("ESC") end -- Need to escape byte.
- wputxb(n)
-end
-
-------------------------------------------------------------------------------
-
--- Global label name -> global label number. With auto assignment on 1st use.
-local next_global = 10
-local map_global = setmetatable({}, { __index = function(t, name)
- if not match(name, "^[%a_][%w_@]*$") then werror("bad global label") end
- local n = next_global
- if n > 246 then werror("too many global labels") end
- next_global = n + 1
- t[name] = n
- return n
-end})
-
--- Dump global labels.
-local function dumpglobals(out, lvl)
- local t = {}
- for name, n in pairs(map_global) do t[n] = name end
- out:write("Global labels:\n")
- for i=10,next_global-1 do
- out:write(format(" %s\n", t[i]))
- end
- out:write("\n")
-end
-
--- Write global label enum.
-local function writeglobals(out, prefix)
- local t = {}
- for name, n in pairs(map_global) do t[n] = name end
- out:write("enum {\n")
- for i=10,next_global-1 do
- out:write(" ", prefix, gsub(t[i], "@.*", ""), ",\n")
- end
- out:write(" ", prefix, "_MAX\n};\n")
-end
-
--- Write global label names.
-local function writeglobalnames(out, name)
- local t = {}
- for name, n in pairs(map_global) do t[n] = name end
- out:write("static const char *const ", name, "[] = {\n")
- for i=10,next_global-1 do
- out:write(" \"", t[i], "\",\n")
- end
- out:write(" (const char *)0\n};\n")
-end
-
-------------------------------------------------------------------------------
-
--- Extern label name -> extern label number. With auto assignment on 1st use.
-local next_extern = -1
-local map_extern = setmetatable({}, { __index = function(t, name)
- -- No restrictions on the name for now.
- local n = next_extern
- if n < -256 then werror("too many extern labels") end
- next_extern = n - 1
- t[name] = n
- return n
-end})
-
--- Dump extern labels.
-local function dumpexterns(out, lvl)
- local t = {}
- for name, n in pairs(map_extern) do t[-n] = name end
- out:write("Extern labels:\n")
- for i=1,-next_extern-1 do
- out:write(format(" %s\n", t[i]))
- end
- out:write("\n")
-end
-
--- Write extern label names.
-local function writeexternnames(out, name)
- local t = {}
- for name, n in pairs(map_extern) do t[-n] = name end
- out:write("static const char *const ", name, "[] = {\n")
- for i=1,-next_extern-1 do
- out:write(" \"", t[i], "\",\n")
- end
- out:write(" (const char *)0\n};\n")
-end
-
-------------------------------------------------------------------------------
-
--- Arch-specific maps.
-local map_archdef = {} -- Ext. register name -> int. name.
-local map_reg_rev = {} -- Int. register name -> ext. name.
-local map_reg_num = {} -- Int. register name -> register number.
-local map_reg_opsize = {} -- Int. register name -> operand size.
-local map_reg_valid_base = {} -- Int. register name -> valid base register?
-local map_reg_valid_index = {} -- Int. register name -> valid index register?
-local map_reg_needrex = {} -- Int. register name -> need rex vs. no rex.
-local reg_list = {} -- Canonical list of int. register names.
-
-local map_type = {} -- Type name -> { ctype, reg }
-local ctypenum = 0 -- Type number (for _PTx macros).
-
-local addrsize = x64 and "q" or "d" -- Size for address operands.
-
--- Helper functions to fill register maps.
-local function mkrmap(sz, cl, names)
- local cname = format("@%s", sz)
- reg_list[#reg_list+1] = cname
- map_archdef[cl] = cname
- map_reg_rev[cname] = cl
- map_reg_num[cname] = -1
- map_reg_opsize[cname] = sz
- if sz == addrsize or sz == "d" then
- map_reg_valid_base[cname] = true
- map_reg_valid_index[cname] = true
- end
- if names then
- for n,name in ipairs(names) do
- local iname = format("@%s%x", sz, n-1)
- reg_list[#reg_list+1] = iname
- map_archdef[name] = iname
- map_reg_rev[iname] = name
- map_reg_num[iname] = n-1
- map_reg_opsize[iname] = sz
- if sz == "b" and n > 4 then map_reg_needrex[iname] = false end
- if sz == addrsize or sz == "d" then
- map_reg_valid_base[iname] = true
- map_reg_valid_index[iname] = true
- end
- end
- end
- for i=0,(x64 and sz ~= "f") and 15 or 7 do
- local needrex = sz == "b" and i > 3
- local iname = format("@%s%x%s", sz, i, needrex and "R" or "")
- if needrex then map_reg_needrex[iname] = true end
- local name
- if sz == "o" then name = format("xmm%d", i)
- elseif sz == "f" then name = format("st%d", i)
- else name = format("r%d%s", i, sz == addrsize and "" or sz) end
- map_archdef[name] = iname
- if not map_reg_rev[iname] then
- reg_list[#reg_list+1] = iname
- map_reg_rev[iname] = name
- map_reg_num[iname] = i
- map_reg_opsize[iname] = sz
- if sz == addrsize or sz == "d" then
- map_reg_valid_base[iname] = true
- map_reg_valid_index[iname] = true
- end
- end
- end
- reg_list[#reg_list+1] = ""
-end
-
--- Integer registers (qword, dword, word and byte sized).
-if x64 then
- mkrmap("q", "Rq", {"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi"})
-end
-mkrmap("d", "Rd", {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"})
-mkrmap("w", "Rw", {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"})
-mkrmap("b", "Rb", {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"})
-map_reg_valid_index[map_archdef.esp] = false
-if x64 then map_reg_valid_index[map_archdef.rsp] = false end
-map_archdef["Ra"] = "@"..addrsize
-
--- FP registers (internally tword sized, but use "f" as operand size).
-mkrmap("f", "Rf")
-
--- SSE registers (oword sized, but qword and dword accessible).
-mkrmap("o", "xmm")
-
--- Operand size prefixes to codes.
-local map_opsize = {
- byte = "b", word = "w", dword = "d", qword = "q", oword = "o", tword = "t",
- aword = addrsize,
-}
-
--- Operand size code to number.
-local map_opsizenum = {
- b = 1, w = 2, d = 4, q = 8, o = 16, t = 10,
-}
-
--- Operand size code to name.
-local map_opsizename = {
- b = "byte", w = "word", d = "dword", q = "qword", o = "oword", t = "tword",
- f = "fpword",
-}
-
--- Valid index register scale factors.
-local map_xsc = {
- ["1"] = 0, ["2"] = 1, ["4"] = 2, ["8"] = 3,
-}
-
--- Condition codes.
-local map_cc = {
- o = 0, no = 1, b = 2, nb = 3, e = 4, ne = 5, be = 6, nbe = 7,
- s = 8, ns = 9, p = 10, np = 11, l = 12, nl = 13, le = 14, nle = 15,
- c = 2, nae = 2, nc = 3, ae = 3, z = 4, nz = 5, na = 6, a = 7,
- pe = 10, po = 11, nge = 12, ge = 13, ng = 14, g = 15,
-}
-
-
--- Reverse defines for registers.
-function _M.revdef(s)
- return gsub(s, "@%w+", map_reg_rev)
-end
-
--- Dump register names and numbers
-local function dumpregs(out)
- out:write("Register names, sizes and internal numbers:\n")
- for _,reg in ipairs(reg_list) do
- if reg == "" then
- out:write("\n")
- else
- local name = map_reg_rev[reg]
- local num = map_reg_num[reg]
- local opsize = map_opsizename[map_reg_opsize[reg]]
- out:write(format(" %-5s %-8s %s\n", name, opsize,
- num < 0 and "(variable)" or num))
- end
- end
-end
-
-------------------------------------------------------------------------------
-
--- Put action for label arg (IMM_LG, IMM_PC, REL_LG, REL_PC).
-local function wputlabel(aprefix, imm, num)
- if type(imm) == "number" then
- if imm < 0 then
- waction("EXTERN")
- wputxb(aprefix == "IMM_" and 0 or 1)
- imm = -imm-1
- else
- waction(aprefix.."LG", nil, num);
- end
- wputxb(imm)
- else
- waction(aprefix.."PC", imm, num)
- end
-end
-
--- Put signed byte or arg.
-local function wputsbarg(n)
- if type(n) == "number" then
- if n < -128 or n > 127 then
- werror("signed immediate byte out of range")
- end
- if n < 0 then n = n + 256 end
- wputb(n)
- else waction("IMM_S", n) end
-end
-
--- Put unsigned byte or arg.
-local function wputbarg(n)
- if type(n) == "number" then
- if n < 0 or n > 255 then
- werror("unsigned immediate byte out of range")
- end
- wputb(n)
- else waction("IMM_B", n) end
-end
-
--- Put unsigned word or arg.
-local function wputwarg(n)
- if type(n) == "number" then
- if shr(n, 16) ~= 0 then
- werror("unsigned immediate word out of range")
- end
- wputb(band(n, 255)); wputb(shr(n, 8));
- else waction("IMM_W", n) end
-end
-
--- Put signed or unsigned dword or arg.
-local function wputdarg(n)
- local tn = type(n)
- if tn == "number" then
- wputb(band(n, 255))
- wputb(band(shr(n, 8), 255))
- wputb(band(shr(n, 16), 255))
- wputb(shr(n, 24))
- elseif tn == "table" then
- wputlabel("IMM_", n[1], 1)
- else
- waction("IMM_D", n)
- end
-end
-
--- Put operand-size dependent number or arg (defaults to dword).
-local function wputszarg(sz, n)
- if not sz or sz == "d" or sz == "q" then wputdarg(n)
- elseif sz == "w" then wputwarg(n)
- elseif sz == "b" then wputbarg(n)
- elseif sz == "s" then wputsbarg(n)
- else werror("bad operand size") end
-end
-
--- Put multi-byte opcode with operand-size dependent modifications.
-local function wputop(sz, op, rex)
- local r
- if rex ~= 0 and not x64 then werror("bad operand size") end
- if sz == "w" then wputb(102) end
- -- Needs >32 bit numbers, but only for crc32 eax, word [ebx]
- if op >= 4294967296 then r = op%4294967296 wputb((op-r)/4294967296) op = r end
- if op >= 16777216 then wputb(shr(op, 24)); op = band(op, 0xffffff) end
- if op >= 65536 then
- if rex ~= 0 then
- local opc3 = band(op, 0xffff00)
- if opc3 == 0x0f3a00 or opc3 == 0x0f3800 then
- wputb(64 + band(rex, 15)); rex = 0
- end
- end
- wputb(shr(op, 16)); op = band(op, 0xffff)
- end
- if op >= 256 then
- local b = shr(op, 8)
- if b == 15 and rex ~= 0 then wputb(64 + band(rex, 15)); rex = 0 end
- wputb(b)
- op = band(op, 255)
- end
- if rex ~= 0 then wputb(64 + band(rex, 15)) end
- if sz == "b" then op = op - 1 end
- wputb(op)
-end
-
--- Put ModRM or SIB formatted byte.
-local function wputmodrm(m, s, rm, vs, vrm)
- assert(m < 4 and s < 16 and rm < 16, "bad modrm operands")
- wputb(shl(m, 6) + shl(band(s, 7), 3) + band(rm, 7))
-end
-
--- Put ModRM/SIB plus optional displacement.
-local function wputmrmsib(t, imark, s, vsreg)
- local vreg, vxreg
- local reg, xreg = t.reg, t.xreg
- if reg and reg < 0 then reg = 0; vreg = t.vreg end
- if xreg and xreg < 0 then xreg = 0; vxreg = t.vxreg end
- if s < 0 then s = 0 end
-
- -- Register mode.
- if sub(t.mode, 1, 1) == "r" then
- wputmodrm(3, s, reg)
- if vsreg then waction("VREG", vsreg); wputxb(2) end
- if vreg then waction("VREG", vreg); wputxb(0) end
- return
- end
-
- local disp = t.disp
- local tdisp = type(disp)
- -- No base register?
- if not reg then
- local riprel = false
- if xreg then
- -- Indexed mode with index register only.
- -- [xreg*xsc+disp] -> (0, s, esp) (xsc, xreg, ebp)
- wputmodrm(0, s, 4)
- if imark == "I" then waction("MARK") end
- if vsreg then waction("VREG", vsreg); wputxb(2) end
- wputmodrm(t.xsc, xreg, 5)
- if vxreg then waction("VREG", vxreg); wputxb(3) end
- else
- -- Pure 32 bit displacement.
- if x64 and tdisp ~= "table" then
- wputmodrm(0, s, 4) -- [disp] -> (0, s, esp) (0, esp, ebp)
- if imark == "I" then waction("MARK") end
- wputmodrm(0, 4, 5)
- else
- riprel = x64
- wputmodrm(0, s, 5) -- [disp|rip-label] -> (0, s, ebp)
- if imark == "I" then waction("MARK") end
- end
- if vsreg then waction("VREG", vsreg); wputxb(2) end
- end
- if riprel then -- Emit rip-relative displacement.
- if match("UWSiI", imark) then
- werror("NYI: rip-relative displacement followed by immediate")
- end
- -- The previous byte in the action buffer cannot be 0xe9 or 0x80-0x8f.
- wputlabel("REL_", disp[1], 2)
- else
- wputdarg(disp)
- end
- return
- end
-
- local m
- if tdisp == "number" then -- Check displacement size at assembly time.
- if disp == 0 and band(reg, 7) ~= 5 then -- [ebp] -> [ebp+0] (in SIB, too)
- if not vreg then m = 0 end -- Force DISP to allow [Rd(5)] -> [ebp+0]
- elseif disp >= -128 and disp <= 127 then m = 1
- else m = 2 end
- elseif tdisp == "table" then
- m = 2
- end
-
- -- Index register present or esp as base register: need SIB encoding.
- if xreg or band(reg, 7) == 4 then
- wputmodrm(m or 2, s, 4) -- ModRM.
- if m == nil or imark == "I" then waction("MARK") end
- if vsreg then waction("VREG", vsreg); wputxb(2) end
- wputmodrm(t.xsc or 0, xreg or 4, reg) -- SIB.
- if vxreg then waction("VREG", vxreg); wputxb(3) end
- if vreg then waction("VREG", vreg); wputxb(1) end
- else
- wputmodrm(m or 2, s, reg) -- ModRM.
- if (imark == "I" and (m == 1 or m == 2)) or
- (m == nil and (vsreg or vreg)) then waction("MARK") end
- if vsreg then waction("VREG", vsreg); wputxb(2) end
- if vreg then waction("VREG", vreg); wputxb(1) end
- end
-
- -- Put displacement.
- if m == 1 then wputsbarg(disp)
- elseif m == 2 then wputdarg(disp)
- elseif m == nil then waction("DISP", disp) end
-end
-
-------------------------------------------------------------------------------
-
--- Return human-readable operand mode string.
-local function opmodestr(op, args)
- local m = {}
- for i=1,#args do
- local a = args[i]
- m[#m+1] = sub(a.mode, 1, 1)..(a.opsize or "?")
- end
- return op.." "..concat(m, ",")
-end
-
--- Convert number to valid integer or nil.
-local function toint(expr)
- local n = tonumber(expr)
- if n then
- if n % 1 ~= 0 or n < -2147483648 or n > 4294967295 then
- werror("bad integer number `"..expr.."'")
- end
- return n
- end
-end
-
--- Parse immediate expression.
-local function immexpr(expr)
- -- &expr (pointer)
- if sub(expr, 1, 1) == "&" then
- return "iPJ", format("(ptrdiff_t)(%s)", sub(expr,2))
- end
-
- local prefix = sub(expr, 1, 2)
- -- =>expr (pc label reference)
- if prefix == "=>" then
- return "iJ", sub(expr, 3)
- end
- -- ->name (global label reference)
- if prefix == "->" then
- return "iJ", map_global[sub(expr, 3)]
- end
-
- -- [<>][1-9] (local label reference)
- local dir, lnum = match(expr, "^([<>])([1-9])$")
- if dir then -- Fwd: 247-255, Bkwd: 1-9.
- return "iJ", lnum + (dir == ">" and 246 or 0)
- end
-
- local extname = match(expr, "^extern%s+(%S+)$")
- if extname then
- return "iJ", map_extern[extname]
- end
-
- -- expr (interpreted as immediate)
- return "iI", expr
-end
-
--- Parse displacement expression: +-num, +-expr, +-opsize*num
-local function dispexpr(expr)
- local disp = expr == "" and 0 or toint(expr)
- if disp then return disp end
- local c, dispt = match(expr, "^([+-])%s*(.+)$")
- if c == "+" then
- expr = dispt
- elseif not c then
- werror("bad displacement expression `"..expr.."'")
- end
- local opsize, tailops = match(dispt, "^(%w+)%s*%*%s*(.+)$")
- local ops, imm = map_opsize[opsize], toint(tailops)
- if ops and imm then
- if c == "-" then imm = -imm end
- return imm*map_opsizenum[ops]
- end
- local mode, iexpr = immexpr(dispt)
- if mode == "iJ" then
- if c == "-" then werror("cannot invert label reference") end
- return { iexpr }
- end
- return expr -- Need to return original signed expression.
-end
-
--- Parse register or type expression.
-local function rtexpr(expr)
- if not expr then return end
- local tname, ovreg = match(expr, "^([%w_]+):(@[%w_]+)$")
- local tp = map_type[tname or expr]
- if tp then
- local reg = ovreg or tp.reg
- local rnum = map_reg_num[reg]
- if not rnum then
- werror("type `"..(tname or expr).."' needs a register override")
- end
- if not map_reg_valid_base[reg] then
- werror("bad base register override `"..(map_reg_rev[reg] or reg).."'")
- end
- return reg, rnum, tp
- end
- return expr, map_reg_num[expr]
-end
-
--- Parse operand and return { mode, opsize, reg, xreg, xsc, disp, imm }.
-local function parseoperand(param)
- local t = {}
-
- local expr = param
- local opsize, tailops = match(param, "^(%w+)%s*(.+)$")
- if opsize then
- t.opsize = map_opsize[opsize]
- if t.opsize then expr = tailops end
- end
-
- local br = match(expr, "^%[%s*(.-)%s*%]$")
- repeat
- if br then
- t.mode = "xm"
-
- -- [disp]
- t.disp = toint(br)
- if t.disp then
- t.mode = x64 and "xm" or "xmO"
- break
- end
-
- -- [reg...]
- local tp
- local reg, tailr = match(br, "^([@%w_:]+)%s*(.*)$")
- reg, t.reg, tp = rtexpr(reg)
- if not t.reg then
- -- [expr]
- t.mode = x64 and "xm" or "xmO"
- t.disp = dispexpr("+"..br)
- break
- end
-
- if t.reg == -1 then
- t.vreg, tailr = match(tailr, "^(%b())(.*)$")
- if not t.vreg then werror("bad variable register expression") end
- end
-
- -- [xreg*xsc] or [xreg*xsc+-disp] or [xreg*xsc+-expr]
- local xsc, tailsc = match(tailr, "^%*%s*([1248])%s*(.*)$")
- if xsc then
- if not map_reg_valid_index[reg] then
- werror("bad index register `"..map_reg_rev[reg].."'")
- end
- t.xsc = map_xsc[xsc]
- t.xreg = t.reg
- t.vxreg = t.vreg
- t.reg = nil
- t.vreg = nil
- t.disp = dispexpr(tailsc)
- break
- end
- if not map_reg_valid_base[reg] then
- werror("bad base register `"..map_reg_rev[reg].."'")
- end
-
- -- [reg] or [reg+-disp]
- t.disp = toint(tailr) or (tailr == "" and 0)
- if t.disp then break end
-
- -- [reg+xreg...]
- local xreg, tailx = match(tailr, "^+%s*([@%w_:]+)%s*(.*)$")
- xreg, t.xreg, tp = rtexpr(xreg)
- if not t.xreg then
- -- [reg+-expr]
- t.disp = dispexpr(tailr)
- break
- end
- if not map_reg_valid_index[xreg] then
- werror("bad index register `"..map_reg_rev[xreg].."'")
- end
-
- if t.xreg == -1 then
- t.vxreg, tailx = match(tailx, "^(%b())(.*)$")
- if not t.vxreg then werror("bad variable register expression") end
- end
-
- -- [reg+xreg*xsc...]
- local xsc, tailsc = match(tailx, "^%*%s*([1248])%s*(.*)$")
- if xsc then
- t.xsc = map_xsc[xsc]
- tailx = tailsc
- end
-
- -- [...] or [...+-disp] or [...+-expr]
- t.disp = dispexpr(tailx)
- else
- -- imm or opsize*imm
- local imm = toint(expr)
- if not imm and sub(expr, 1, 1) == "*" and t.opsize then
- imm = toint(sub(expr, 2))
- if imm then
- imm = imm * map_opsizenum[t.opsize]
- t.opsize = nil
- end
- end
- if imm then
- if t.opsize then werror("bad operand size override") end
- local m = "i"
- if imm == 1 then m = m.."1" end
- if imm >= 4294967168 and imm <= 4294967295 then imm = imm-4294967296 end
- if imm >= -128 and imm <= 127 then m = m.."S" end
- t.imm = imm
- t.mode = m
- break
- end
-
- local tp
- local reg, tailr = match(expr, "^([@%w_:]+)%s*(.*)$")
- reg, t.reg, tp = rtexpr(reg)
- if t.reg then
- if t.reg == -1 then
- t.vreg, tailr = match(tailr, "^(%b())(.*)$")
- if not t.vreg then werror("bad variable register expression") end
- end
- -- reg
- if tailr == "" then
- if t.opsize then werror("bad operand size override") end
- t.opsize = map_reg_opsize[reg]
- if t.opsize == "f" then
- t.mode = t.reg == 0 and "fF" or "f"
- else
- if reg == "@w4" or (x64 and reg == "@d4") then
- wwarn("bad idea, try again with `"..(x64 and "rsp'" or "esp'"))
- end
- t.mode = t.reg == 0 and "rmR" or (reg == "@b1" and "rmC" or "rm")
- end
- t.needrex = map_reg_needrex[reg]
- break
- end
-
- -- type[idx], type[idx].field, type->field -> [reg+offset_expr]
- if not tp then werror("bad operand `"..param.."'") end
- t.mode = "xm"
- t.disp = format(tp.ctypefmt, tailr)
- else
- t.mode, t.imm = immexpr(expr)
- if sub(t.mode, -1) == "J" then
- if t.opsize and t.opsize ~= addrsize then
- werror("bad operand size override")
- end
- t.opsize = addrsize
- end
- end
- end
- until true
- return t
-end
-
-------------------------------------------------------------------------------
--- x86 Template String Description
--- ===============================
---
--- Each template string is a list of [match:]pattern pairs,
--- separated by "|". The first match wins. No match means a
--- bad or unsupported combination of operand modes or sizes.
---
--- The match part and the ":" is omitted if the operation has
--- no operands. Otherwise the first N characters are matched
--- against the mode strings of each of the N operands.
---
--- The mode string for each operand type is (see parseoperand()):
--- Integer register: "rm", +"R" for eax, ax, al, +"C" for cl
--- FP register: "f", +"F" for st0
--- Index operand: "xm", +"O" for [disp] (pure offset)
--- Immediate: "i", +"S" for signed 8 bit, +"1" for 1,
--- +"I" for arg, +"P" for pointer
--- Any: +"J" for valid jump targets
---
--- So a match character "m" (mixed) matches both an integer register
--- and an index operand (to be encoded with the ModRM/SIB scheme).
--- But "r" matches only a register and "x" only an index operand
--- (e.g. for FP memory access operations).
---
--- The operand size match string starts right after the mode match
--- characters and ends before the ":". "dwb" or "qdwb" is assumed, if empty.
--- The effective data size of the operation is matched against this list.
---
--- If only the regular "b", "w", "d", "q", "t" operand sizes are
--- present, then all operands must be the same size. Unspecified sizes
--- are ignored, but at least one operand must have a size or the pattern
--- won't match (use the "byte", "word", "dword", "qword", "tword"
--- operand size overrides. E.g.: mov dword [eax], 1).
---
--- If the list has a "1" or "2" prefix, the operand size is taken
--- from the respective operand and any other operand sizes are ignored.
--- If the list contains only ".", all operand sizes are ignored.
--- If the list has a "/" prefix, the concatenated (mixed) operand sizes
--- are compared to the match.
---
--- E.g. "rrdw" matches for either two dword registers or two word
--- registers. "Fx2dq" matches an st0 operand plus an index operand
--- pointing to a dword (float) or qword (double).
---
--- Every character after the ":" is part of the pattern string:
--- Hex chars are accumulated to form the opcode (left to right).
--- "n" disables the standard opcode mods
--- (otherwise: -1 for "b", o16 prefix for "w", rex.w for "q")
--- "X" Force REX.W.
--- "r"/"R" adds the reg. number from the 1st/2nd operand to the opcode.
--- "m"/"M" generates ModRM/SIB from the 1st/2nd operand.
--- The spare 3 bits are either filled with the last hex digit or
--- the result from a previous "r"/"R". The opcode is restored.
---
--- All of the following characters force a flush of the opcode:
--- "o"/"O" stores a pure 32 bit disp (offset) from the 1st/2nd operand.
--- "S" stores a signed 8 bit immediate from the last operand.
--- "U" stores an unsigned 8 bit immediate from the last operand.
--- "W" stores an unsigned 16 bit immediate from the last operand.
--- "i" stores an operand sized immediate from the last operand.
--- "I" dito, but generates an action code to optionally modify
--- the opcode (+2) for a signed 8 bit immediate.
--- "J" generates one of the REL action codes from the last operand.
---
-------------------------------------------------------------------------------
-
--- Template strings for x86 instructions. Ordered by first opcode byte.
--- Unimplemented opcodes (deliberate omissions) are marked with *.
-local map_op = {
- -- 00-05: add...
- -- 06: *push es
- -- 07: *pop es
- -- 08-0D: or...
- -- 0E: *push cs
- -- 0F: two byte opcode prefix
- -- 10-15: adc...
- -- 16: *push ss
- -- 17: *pop ss
- -- 18-1D: sbb...
- -- 1E: *push ds
- -- 1F: *pop ds
- -- 20-25: and...
- es_0 = "26",
- -- 27: *daa
- -- 28-2D: sub...
- cs_0 = "2E",
- -- 2F: *das
- -- 30-35: xor...
- ss_0 = "36",
- -- 37: *aaa
- -- 38-3D: cmp...
- ds_0 = "3E",
- -- 3F: *aas
- inc_1 = x64 and "m:FF0m" or "rdw:40r|m:FF0m",
- dec_1 = x64 and "m:FF1m" or "rdw:48r|m:FF1m",
- push_1 = (x64 and "rq:n50r|rw:50r|mq:nFF6m|mw:FF6m" or
- "rdw:50r|mdw:FF6m").."|S.:6AS|ib:n6Ai|i.:68i",
- pop_1 = x64 and "rq:n58r|rw:58r|mq:n8F0m|mw:8F0m" or "rdw:58r|mdw:8F0m",
- -- 60: *pusha, *pushad, *pushaw
- -- 61: *popa, *popad, *popaw
- -- 62: *bound rdw,x
- -- 63: x86: *arpl mw,rw
- movsxd_2 = x64 and "rm/qd:63rM",
- fs_0 = "64",
- gs_0 = "65",
- o16_0 = "66",
- a16_0 = not x64 and "67" or nil,
- a32_0 = x64 and "67",
- -- 68: push idw
- -- 69: imul rdw,mdw,idw
- -- 6A: push ib
- -- 6B: imul rdw,mdw,S
- -- 6C: *insb
- -- 6D: *insd, *insw
- -- 6E: *outsb
- -- 6F: *outsd, *outsw
- -- 70-7F: jcc lb
- -- 80: add... mb,i
- -- 81: add... mdw,i
- -- 82: *undefined
- -- 83: add... mdw,S
- test_2 = "mr:85Rm|rm:85rM|Ri:A9ri|mi:F70mi",
- -- 86: xchg rb,mb
- -- 87: xchg rdw,mdw
- -- 88: mov mb,r
- -- 89: mov mdw,r
- -- 8A: mov r,mb
- -- 8B: mov r,mdw
- -- 8C: *mov mdw,seg
- lea_2 = "rx1dq:8DrM",
- -- 8E: *mov seg,mdw
- -- 8F: pop mdw
- nop_0 = "90",
- xchg_2 = "Rrqdw:90R|rRqdw:90r|rm:87rM|mr:87Rm",
- cbw_0 = "6698",
- cwde_0 = "98",
- cdqe_0 = "4898",
- cwd_0 = "6699",
- cdq_0 = "99",
- cqo_0 = "4899",
- -- 9A: *call iw:idw
- wait_0 = "9B",
- fwait_0 = "9B",
- pushf_0 = "9C",
- pushfd_0 = not x64 and "9C",
- pushfq_0 = x64 and "9C",
- popf_0 = "9D",
- popfd_0 = not x64 and "9D",
- popfq_0 = x64 and "9D",
- sahf_0 = "9E",
- lahf_0 = "9F",
- mov_2 = "OR:A3o|RO:A1O|mr:89Rm|rm:8BrM|rib:nB0ri|ridw:B8ri|mi:C70mi",
- movsb_0 = "A4",
- movsw_0 = "66A5",
- movsd_0 = "A5",
- cmpsb_0 = "A6",
- cmpsw_0 = "66A7",
- cmpsd_0 = "A7",
- -- A8: test Rb,i
- -- A9: test Rdw,i
- stosb_0 = "AA",
- stosw_0 = "66AB",
- stosd_0 = "AB",
- lodsb_0 = "AC",
- lodsw_0 = "66AD",
- lodsd_0 = "AD",
- scasb_0 = "AE",
- scasw_0 = "66AF",
- scasd_0 = "AF",
- -- B0-B7: mov rb,i
- -- B8-BF: mov rdw,i
- -- C0: rol... mb,i
- -- C1: rol... mdw,i
- ret_1 = "i.:nC2W",
- ret_0 = "C3",
- -- C4: *les rdw,mq
- -- C5: *lds rdw,mq
- -- C6: mov mb,i
- -- C7: mov mdw,i
- -- C8: *enter iw,ib
- leave_0 = "C9",
- -- CA: *retf iw
- -- CB: *retf
- int3_0 = "CC",
- int_1 = "i.:nCDU",
- into_0 = "CE",
- -- CF: *iret
- -- D0: rol... mb,1
- -- D1: rol... mdw,1
- -- D2: rol... mb,cl
- -- D3: rol... mb,cl
- -- D4: *aam ib
- -- D5: *aad ib
- -- D6: *salc
- -- D7: *xlat
- -- D8-DF: floating point ops
- -- E0: *loopne
- -- E1: *loope
- -- E2: *loop
- -- E3: *jcxz, *jecxz
- -- E4: *in Rb,ib
- -- E5: *in Rdw,ib
- -- E6: *out ib,Rb
- -- E7: *out ib,Rdw
- call_1 = x64 and "mq:nFF2m|J.:E8nJ" or "md:FF2m|J.:E8J",
- jmp_1 = x64 and "mq:nFF4m|J.:E9nJ" or "md:FF4m|J.:E9J", -- short: EB
- -- EA: *jmp iw:idw
- -- EB: jmp ib
- -- EC: *in Rb,dx
- -- ED: *in Rdw,dx
- -- EE: *out dx,Rb
- -- EF: *out dx,Rdw
- lock_0 = "F0",
- int1_0 = "F1",
- repne_0 = "F2",
- repnz_0 = "F2",
- rep_0 = "F3",
- repe_0 = "F3",
- repz_0 = "F3",
- -- F4: *hlt
- cmc_0 = "F5",
- -- F6: test... mb,i; div... mb
- -- F7: test... mdw,i; div... mdw
- clc_0 = "F8",
- stc_0 = "F9",
- -- FA: *cli
- cld_0 = "FC",
- std_0 = "FD",
- -- FE: inc... mb
- -- FF: inc... mdw
-
- -- misc ops
- not_1 = "m:F72m",
- neg_1 = "m:F73m",
- mul_1 = "m:F74m",
- imul_1 = "m:F75m",
- div_1 = "m:F76m",
- idiv_1 = "m:F77m",
-
- imul_2 = "rmqdw:0FAFrM|rIqdw:69rmI|rSqdw:6BrmS|riqdw:69rmi",
- imul_3 = "rmIqdw:69rMI|rmSqdw:6BrMS|rmiqdw:69rMi",
-
- movzx_2 = "rm/db:0FB6rM|rm/qb:|rm/wb:0FB6rM|rm/dw:0FB7rM|rm/qw:",
- movsx_2 = "rm/db:0FBErM|rm/qb:|rm/wb:0FBErM|rm/dw:0FBFrM|rm/qw:",
-
- bswap_1 = "rqd:0FC8r",
- bsf_2 = "rmqdw:0FBCrM",
- bsr_2 = "rmqdw:0FBDrM",
- bt_2 = "mrqdw:0FA3Rm|miqdw:0FBA4mU",
- btc_2 = "mrqdw:0FBBRm|miqdw:0FBA7mU",
- btr_2 = "mrqdw:0FB3Rm|miqdw:0FBA6mU",
- bts_2 = "mrqdw:0FABRm|miqdw:0FBA5mU",
-
- shld_3 = "mriqdw:0FA4RmU|mrCqdw:0FA5Rm",
- shrd_3 = "mriqdw:0FACRmU|mrCqdw:0FADRm",
-
- rdtsc_0 = "0F31", -- P1+
- cpuid_0 = "0FA2", -- P1+
-
- -- floating point ops
- fst_1 = "ff:DDD0r|xd:D92m|xq:nDD2m",
- fstp_1 = "ff:DDD8r|xd:D93m|xq:nDD3m|xt:DB7m",
- fld_1 = "ff:D9C0r|xd:D90m|xq:nDD0m|xt:DB5m",
-
- fpop_0 = "DDD8", -- Alias for fstp st0.
-
- fist_1 = "xw:nDF2m|xd:DB2m",
- fistp_1 = "xw:nDF3m|xd:DB3m|xq:nDF7m",
- fild_1 = "xw:nDF0m|xd:DB0m|xq:nDF5m",
-
- fxch_0 = "D9C9",
- fxch_1 = "ff:D9C8r",
- fxch_2 = "fFf:D9C8r|Fff:D9C8R",
-
- fucom_1 = "ff:DDE0r",
- fucom_2 = "Fff:DDE0R",
- fucomp_1 = "ff:DDE8r",
- fucomp_2 = "Fff:DDE8R",
- fucomi_1 = "ff:DBE8r", -- P6+
- fucomi_2 = "Fff:DBE8R", -- P6+
- fucomip_1 = "ff:DFE8r", -- P6+
- fucomip_2 = "Fff:DFE8R", -- P6+
- fcomi_1 = "ff:DBF0r", -- P6+
- fcomi_2 = "Fff:DBF0R", -- P6+
- fcomip_1 = "ff:DFF0r", -- P6+
- fcomip_2 = "Fff:DFF0R", -- P6+
- fucompp_0 = "DAE9",
- fcompp_0 = "DED9",
-
- fldenv_1 = "x.:D94m",
- fnstenv_1 = "x.:D96m",
- fstenv_1 = "x.:9BD96m",
- fldcw_1 = "xw:nD95m",
- fstcw_1 = "xw:n9BD97m",
- fnstcw_1 = "xw:nD97m",
- fstsw_1 = "Rw:n9BDFE0|xw:n9BDD7m",
- fnstsw_1 = "Rw:nDFE0|xw:nDD7m",
- fclex_0 = "9BDBE2",
- fnclex_0 = "DBE2",
-
- fnop_0 = "D9D0",
- -- D9D1-D9DF: unassigned
-
- fchs_0 = "D9E0",
- fabs_0 = "D9E1",
- -- D9E2: unassigned
- -- D9E3: unassigned
- ftst_0 = "D9E4",
- fxam_0 = "D9E5",
- -- D9E6: unassigned
- -- D9E7: unassigned
- fld1_0 = "D9E8",
- fldl2t_0 = "D9E9",
- fldl2e_0 = "D9EA",
- fldpi_0 = "D9EB",
- fldlg2_0 = "D9EC",
- fldln2_0 = "D9ED",
- fldz_0 = "D9EE",
- -- D9EF: unassigned
-
- f2xm1_0 = "D9F0",
- fyl2x_0 = "D9F1",
- fptan_0 = "D9F2",
- fpatan_0 = "D9F3",
- fxtract_0 = "D9F4",
- fprem1_0 = "D9F5",
- fdecstp_0 = "D9F6",
- fincstp_0 = "D9F7",
- fprem_0 = "D9F8",
- fyl2xp1_0 = "D9F9",
- fsqrt_0 = "D9FA",
- fsincos_0 = "D9FB",
- frndint_0 = "D9FC",
- fscale_0 = "D9FD",
- fsin_0 = "D9FE",
- fcos_0 = "D9FF",
-
- -- SSE, SSE2
- andnpd_2 = "rmo:660F55rM",
- andnps_2 = "rmo:0F55rM",
- andpd_2 = "rmo:660F54rM",
- andps_2 = "rmo:0F54rM",
- clflush_1 = "x.:0FAE7m",
- cmppd_3 = "rmio:660FC2rMU",
- cmpps_3 = "rmio:0FC2rMU",
- cmpsd_3 = "rrio:F20FC2rMU|rxi/oq:",
- cmpss_3 = "rrio:F30FC2rMU|rxi/od:",
- comisd_2 = "rro:660F2FrM|rx/oq:",
- comiss_2 = "rro:0F2FrM|rx/od:",
- cvtdq2pd_2 = "rro:F30FE6rM|rx/oq:",
- cvtdq2ps_2 = "rmo:0F5BrM",
- cvtpd2dq_2 = "rmo:F20FE6rM",
- cvtpd2ps_2 = "rmo:660F5ArM",
- cvtpi2pd_2 = "rx/oq:660F2ArM",
- cvtpi2ps_2 = "rx/oq:0F2ArM",
- cvtps2dq_2 = "rmo:660F5BrM",
- cvtps2pd_2 = "rro:0F5ArM|rx/oq:",
- cvtsd2si_2 = "rr/do:F20F2DrM|rr/qo:|rx/dq:|rxq:",
- cvtsd2ss_2 = "rro:F20F5ArM|rx/oq:",
- cvtsi2sd_2 = "rm/od:F20F2ArM|rm/oq:F20F2ArXM",
- cvtsi2ss_2 = "rm/od:F30F2ArM|rm/oq:F30F2ArXM",
- cvtss2sd_2 = "rro:F30F5ArM|rx/od:",
- cvtss2si_2 = "rr/do:F20F2CrM|rr/qo:|rxd:|rx/qd:",
- cvttpd2dq_2 = "rmo:660FE6rM",
- cvttps2dq_2 = "rmo:F30F5BrM",
- cvttsd2si_2 = "rr/do:F20F2CrM|rr/qo:|rx/dq:|rxq:",
- cvttss2si_2 = "rr/do:F30F2CrM|rr/qo:|rxd:|rx/qd:",
- fxsave_1 = "x.:0FAE0m",
- fxrstor_1 = "x.:0FAE1m",
- ldmxcsr_1 = "xd:0FAE2m",
- lfence_0 = "0FAEE8",
- maskmovdqu_2 = "rro:660FF7rM",
- mfence_0 = "0FAEF0",
- movapd_2 = "rmo:660F28rM|mro:660F29Rm",
- movaps_2 = "rmo:0F28rM|mro:0F29Rm",
- movd_2 = "rm/od:660F6ErM|rm/oq:660F6ErXM|mr/do:660F7ERm|mr/qo:",
- movdqa_2 = "rmo:660F6FrM|mro:660F7FRm",
- movdqu_2 = "rmo:F30F6FrM|mro:F30F7FRm",
- movhlps_2 = "rro:0F12rM",
- movhpd_2 = "rx/oq:660F16rM|xr/qo:n660F17Rm",
- movhps_2 = "rx/oq:0F16rM|xr/qo:n0F17Rm",
- movlhps_2 = "rro:0F16rM",
- movlpd_2 = "rx/oq:660F12rM|xr/qo:n660F13Rm",
- movlps_2 = "rx/oq:0F12rM|xr/qo:n0F13Rm",
- movmskpd_2 = "rr/do:660F50rM",
- movmskps_2 = "rr/do:0F50rM",
- movntdq_2 = "xro:660FE7Rm",
- movnti_2 = "xrqd:0FC3Rm",
- movntpd_2 = "xro:660F2BRm",
- movntps_2 = "xro:0F2BRm",
- movq_2 = "rro:F30F7ErM|rx/oq:|xr/qo:n660FD6Rm",
- movsd_2 = "rro:F20F10rM|rx/oq:|xr/qo:nF20F11Rm",
- movss_2 = "rro:F30F10rM|rx/od:|xr/do:F30F11Rm",
- movupd_2 = "rmo:660F10rM|mro:660F11Rm",
- movups_2 = "rmo:0F10rM|mro:0F11Rm",
- orpd_2 = "rmo:660F56rM",
- orps_2 = "rmo:0F56rM",
- packssdw_2 = "rmo:660F6BrM",
- packsswb_2 = "rmo:660F63rM",
- packuswb_2 = "rmo:660F67rM",
- paddb_2 = "rmo:660FFCrM",
- paddd_2 = "rmo:660FFErM",
- paddq_2 = "rmo:660FD4rM",
- paddsb_2 = "rmo:660FECrM",
- paddsw_2 = "rmo:660FEDrM",
- paddusb_2 = "rmo:660FDCrM",
- paddusw_2 = "rmo:660FDDrM",
- paddw_2 = "rmo:660FFDrM",
- pand_2 = "rmo:660FDBrM",
- pandn_2 = "rmo:660FDFrM",
- pause_0 = "F390",
- pavgb_2 = "rmo:660FE0rM",
- pavgw_2 = "rmo:660FE3rM",
- pcmpeqb_2 = "rmo:660F74rM",
- pcmpeqd_2 = "rmo:660F76rM",
- pcmpeqw_2 = "rmo:660F75rM",
- pcmpgtb_2 = "rmo:660F64rM",
- pcmpgtd_2 = "rmo:660F66rM",
- pcmpgtw_2 = "rmo:660F65rM",
- pextrw_3 = "rri/do:660FC5rMU|xri/wo:660F3A15nrMU", -- Mem op: SSE4.1 only.
- pinsrw_3 = "rri/od:660FC4rMU|rxi/ow:",
- pmaddwd_2 = "rmo:660FF5rM",
- pmaxsw_2 = "rmo:660FEErM",
- pmaxub_2 = "rmo:660FDErM",
- pminsw_2 = "rmo:660FEArM",
- pminub_2 = "rmo:660FDArM",
- pmovmskb_2 = "rr/do:660FD7rM",
- pmulhuw_2 = "rmo:660FE4rM",
- pmulhw_2 = "rmo:660FE5rM",
- pmullw_2 = "rmo:660FD5rM",
- pmuludq_2 = "rmo:660FF4rM",
- por_2 = "rmo:660FEBrM",
- prefetchnta_1 = "xb:n0F180m",
- prefetcht0_1 = "xb:n0F181m",
- prefetcht1_1 = "xb:n0F182m",
- prefetcht2_1 = "xb:n0F183m",
- psadbw_2 = "rmo:660FF6rM",
- pshufd_3 = "rmio:660F70rMU",
- pshufhw_3 = "rmio:F30F70rMU",
- pshuflw_3 = "rmio:F20F70rMU",
- pslld_2 = "rmo:660FF2rM|rio:660F726mU",
- pslldq_2 = "rio:660F737mU",
- psllq_2 = "rmo:660FF3rM|rio:660F736mU",
- psllw_2 = "rmo:660FF1rM|rio:660F716mU",
- psrad_2 = "rmo:660FE2rM|rio:660F724mU",
- psraw_2 = "rmo:660FE1rM|rio:660F714mU",
- psrld_2 = "rmo:660FD2rM|rio:660F722mU",
- psrldq_2 = "rio:660F733mU",
- psrlq_2 = "rmo:660FD3rM|rio:660F732mU",
- psrlw_2 = "rmo:660FD1rM|rio:660F712mU",
- psubb_2 = "rmo:660FF8rM",
- psubd_2 = "rmo:660FFArM",
- psubq_2 = "rmo:660FFBrM",
- psubsb_2 = "rmo:660FE8rM",
- psubsw_2 = "rmo:660FE9rM",
- psubusb_2 = "rmo:660FD8rM",
- psubusw_2 = "rmo:660FD9rM",
- psubw_2 = "rmo:660FF9rM",
- punpckhbw_2 = "rmo:660F68rM",
- punpckhdq_2 = "rmo:660F6ArM",
- punpckhqdq_2 = "rmo:660F6DrM",
- punpckhwd_2 = "rmo:660F69rM",
- punpcklbw_2 = "rmo:660F60rM",
- punpckldq_2 = "rmo:660F62rM",
- punpcklqdq_2 = "rmo:660F6CrM",
- punpcklwd_2 = "rmo:660F61rM",
- pxor_2 = "rmo:660FEFrM",
- rcpps_2 = "rmo:0F53rM",
- rcpss_2 = "rro:F30F53rM|rx/od:",
- rsqrtps_2 = "rmo:0F52rM",
- rsqrtss_2 = "rmo:F30F52rM",
- sfence_0 = "0FAEF8",
- shufpd_3 = "rmio:660FC6rMU",
- shufps_3 = "rmio:0FC6rMU",
- stmxcsr_1 = "xd:0FAE3m",
- ucomisd_2 = "rro:660F2ErM|rx/oq:",
- ucomiss_2 = "rro:0F2ErM|rx/od:",
- unpckhpd_2 = "rmo:660F15rM",
- unpckhps_2 = "rmo:0F15rM",
- unpcklpd_2 = "rmo:660F14rM",
- unpcklps_2 = "rmo:0F14rM",
- xorpd_2 = "rmo:660F57rM",
- xorps_2 = "rmo:0F57rM",
-
- -- SSE3 ops
- fisttp_1 = "xw:nDF1m|xd:DB1m|xq:nDD1m",
- addsubpd_2 = "rmo:660FD0rM",
- addsubps_2 = "rmo:F20FD0rM",
- haddpd_2 = "rmo:660F7CrM",
- haddps_2 = "rmo:F20F7CrM",
- hsubpd_2 = "rmo:660F7DrM",
- hsubps_2 = "rmo:F20F7DrM",
- lddqu_2 = "rxo:F20FF0rM",
- movddup_2 = "rmo:F20F12rM",
- movshdup_2 = "rmo:F30F16rM",
- movsldup_2 = "rmo:F30F12rM",
-
- -- SSSE3 ops
- pabsb_2 = "rmo:660F381CrM",
- pabsd_2 = "rmo:660F381ErM",
- pabsw_2 = "rmo:660F381DrM",
- palignr_3 = "rmio:660F3A0FrMU",
- phaddd_2 = "rmo:660F3802rM",
- phaddsw_2 = "rmo:660F3803rM",
- phaddw_2 = "rmo:660F3801rM",
- phsubd_2 = "rmo:660F3806rM",
- phsubsw_2 = "rmo:660F3807rM",
- phsubw_2 = "rmo:660F3805rM",
- pmaddubsw_2 = "rmo:660F3804rM",
- pmulhrsw_2 = "rmo:660F380BrM",
- pshufb_2 = "rmo:660F3800rM",
- psignb_2 = "rmo:660F3808rM",
- psignd_2 = "rmo:660F380ArM",
- psignw_2 = "rmo:660F3809rM",
-
- -- SSE4.1 ops
- blendpd_3 = "rmio:660F3A0DrMU",
- blendps_3 = "rmio:660F3A0CrMU",
- blendvpd_3 = "rmRo:660F3815rM",
- blendvps_3 = "rmRo:660F3814rM",
- dppd_3 = "rmio:660F3A41rMU",
- dpps_3 = "rmio:660F3A40rMU",
- extractps_3 = "mri/do:660F3A17RmU|rri/qo:660F3A17RXmU",
- insertps_3 = "rrio:660F3A41rMU|rxi/od:",
- movntdqa_2 = "rmo:660F382ArM",
- mpsadbw_3 = "rmio:660F3A42rMU",
- packusdw_2 = "rmo:660F382BrM",
- pblendvb_3 = "rmRo:660F3810rM",
- pblendw_3 = "rmio:660F3A0ErMU",
- pcmpeqq_2 = "rmo:660F3829rM",
- pextrb_3 = "rri/do:660F3A14nRmU|rri/qo:|xri/bo:",
- pextrd_3 = "mri/do:660F3A16RmU",
- pextrq_3 = "mri/qo:660F3A16RmU",
- -- pextrw is SSE2, mem operand is SSE4.1 only
- phminposuw_2 = "rmo:660F3841rM",
- pinsrb_3 = "rri/od:660F3A20nrMU|rxi/ob:",
- pinsrd_3 = "rmi/od:660F3A22rMU",
- pinsrq_3 = "rmi/oq:660F3A22rXMU",
- pmaxsb_2 = "rmo:660F383CrM",
- pmaxsd_2 = "rmo:660F383DrM",
- pmaxud_2 = "rmo:660F383FrM",
- pmaxuw_2 = "rmo:660F383ErM",
- pminsb_2 = "rmo:660F3838rM",
- pminsd_2 = "rmo:660F3839rM",
- pminud_2 = "rmo:660F383BrM",
- pminuw_2 = "rmo:660F383ArM",
- pmovsxbd_2 = "rro:660F3821rM|rx/od:",
- pmovsxbq_2 = "rro:660F3822rM|rx/ow:",
- pmovsxbw_2 = "rro:660F3820rM|rx/oq:",
- pmovsxdq_2 = "rro:660F3825rM|rx/oq:",
- pmovsxwd_2 = "rro:660F3823rM|rx/oq:",
- pmovsxwq_2 = "rro:660F3824rM|rx/od:",
- pmovzxbd_2 = "rro:660F3831rM|rx/od:",
- pmovzxbq_2 = "rro:660F3832rM|rx/ow:",
- pmovzxbw_2 = "rro:660F3830rM|rx/oq:",
- pmovzxdq_2 = "rro:660F3835rM|rx/oq:",
- pmovzxwd_2 = "rro:660F3833rM|rx/oq:",
- pmovzxwq_2 = "rro:660F3834rM|rx/od:",
- pmuldq_2 = "rmo:660F3828rM",
- pmulld_2 = "rmo:660F3840rM",
- ptest_2 = "rmo:660F3817rM",
- roundpd_3 = "rmio:660F3A09rMU",
- roundps_3 = "rmio:660F3A08rMU",
- roundsd_3 = "rrio:660F3A0BrMU|rxi/oq:",
- roundss_3 = "rrio:660F3A0ArMU|rxi/od:",
-
- -- SSE4.2 ops
- crc32_2 = "rmqd:F20F38F1rM|rm/dw:66F20F38F1rM|rm/db:F20F38F0rM|rm/qb:",
- pcmpestri_3 = "rmio:660F3A61rMU",
- pcmpestrm_3 = "rmio:660F3A60rMU",
- pcmpgtq_2 = "rmo:660F3837rM",
- pcmpistri_3 = "rmio:660F3A63rMU",
- pcmpistrm_3 = "rmio:660F3A62rMU",
- popcnt_2 = "rmqdw:F30FB8rM",
-
- -- SSE4a
- extrq_2 = "rro:660F79rM",
- extrq_3 = "riio:660F780mUU",
- insertq_2 = "rro:F20F79rM",
- insertq_4 = "rriio:F20F78rMUU",
- lzcnt_2 = "rmqdw:F30FBDrM",
- movntsd_2 = "xr/qo:nF20F2BRm",
- movntss_2 = "xr/do:F30F2BRm",
- -- popcnt is also in SSE4.2
-}
-
-------------------------------------------------------------------------------
-
--- Arithmetic ops.
-for name,n in pairs{ add = 0, ["or"] = 1, adc = 2, sbb = 3,
- ["and"] = 4, sub = 5, xor = 6, cmp = 7 } do
- local n8 = shl(n, 3)
- map_op[name.."_2"] = format(
- "mr:%02XRm|rm:%02XrM|mI1qdw:81%XmI|mS1qdw:83%XmS|Ri1qdwb:%02Xri|mi1qdwb:81%Xmi",
- 1+n8, 3+n8, n, n, 5+n8, n)
-end
-
--- Shift ops.
-for name,n in pairs{ rol = 0, ror = 1, rcl = 2, rcr = 3,
- shl = 4, shr = 5, sar = 7, sal = 4 } do
- map_op[name.."_2"] = format("m1:D1%Xm|mC1qdwb:D3%Xm|mi:C1%XmU", n, n, n)
-end
-
--- Conditional ops.
-for cc,n in pairs(map_cc) do
- map_op["j"..cc.."_1"] = format("J.:n0F8%XJ", n) -- short: 7%X
- map_op["set"..cc.."_1"] = format("mb:n0F9%X2m", n)
- map_op["cmov"..cc.."_2"] = format("rmqdw:0F4%XrM", n) -- P6+
-end
-
--- FP arithmetic ops.
-for name,n in pairs{ add = 0, mul = 1, com = 2, comp = 3,
- sub = 4, subr = 5, div = 6, divr = 7 } do
- local nc = 0xc0 + shl(n, 3)
- local nr = nc + (n < 4 and 0 or (n % 2 == 0 and 8 or -8))
- local fn = "f"..name
- map_op[fn.."_1"] = format("ff:D8%02Xr|xd:D8%Xm|xq:nDC%Xm", nc, n, n)
- if n == 2 or n == 3 then
- map_op[fn.."_2"] = format("Fff:D8%02XR|Fx2d:D8%XM|Fx2q:nDC%XM", nc, n, n)
- else
- map_op[fn.."_2"] = format("Fff:D8%02XR|fFf:DC%02Xr|Fx2d:D8%XM|Fx2q:nDC%XM", nc, nr, n, n)
- map_op[fn.."p_1"] = format("ff:DE%02Xr", nr)
- map_op[fn.."p_2"] = format("fFf:DE%02Xr", nr)
- end
- map_op["fi"..name.."_1"] = format("xd:DA%Xm|xw:nDE%Xm", n, n)
-end
-
--- FP conditional moves.
-for cc,n in pairs{ b=0, e=1, be=2, u=3, nb=4, ne=5, nbe=6, nu=7 } do
- local nc = 0xdac0 + shl(band(n, 3), 3) + shl(band(n, 4), 6)
- map_op["fcmov"..cc.."_1"] = format("ff:%04Xr", nc) -- P6+
- map_op["fcmov"..cc.."_2"] = format("Fff:%04XR", nc) -- P6+
-end
-
--- SSE FP arithmetic ops.
-for name,n in pairs{ sqrt = 1, add = 8, mul = 9,
- sub = 12, min = 13, div = 14, max = 15 } do
- map_op[name.."ps_2"] = format("rmo:0F5%XrM", n)
- map_op[name.."ss_2"] = format("rro:F30F5%XrM|rx/od:", n)
- map_op[name.."pd_2"] = format("rmo:660F5%XrM", n)
- map_op[name.."sd_2"] = format("rro:F20F5%XrM|rx/oq:", n)
-end
-
-------------------------------------------------------------------------------
-
--- Process pattern string.
-local function dopattern(pat, args, sz, op, needrex)
- local digit, addin
- local opcode = 0
- local szov = sz
- local narg = 1
- local rex = 0
-
- -- Limit number of section buffer positions used by a single dasm_put().
- -- A single opcode needs a maximum of 5 positions.
- if secpos+5 > maxsecpos then wflush() end
-
- -- Process each character.
- for c in gmatch(pat.."|", ".") do
- if match(c, "%x") then -- Hex digit.
- digit = byte(c) - 48
- if digit > 48 then digit = digit - 39
- elseif digit > 16 then digit = digit - 7 end
- opcode = opcode*16 + digit
- addin = nil
- elseif c == "n" then -- Disable operand size mods for opcode.
- szov = nil
- elseif c == "X" then -- Force REX.W.
- rex = 8
- elseif c == "r" then -- Merge 1st operand regno. into opcode.
- addin = args[1]; opcode = opcode + (addin.reg % 8)
- if narg < 2 then narg = 2 end
- elseif c == "R" then -- Merge 2nd operand regno. into opcode.
- addin = args[2]; opcode = opcode + (addin.reg % 8)
- narg = 3
- elseif c == "m" or c == "M" then -- Encode ModRM/SIB.
- local s
- if addin then
- s = addin.reg
- opcode = opcode - band(s, 7) -- Undo regno opcode merge.
- else
- s = band(opcode, 15) -- Undo last digit.
- opcode = shr(opcode, 4)
- end
- local nn = c == "m" and 1 or 2
- local t = args[nn]
- if narg <= nn then narg = nn + 1 end
- if szov == "q" and rex == 0 then rex = rex + 8 end
- if t.reg and t.reg > 7 then rex = rex + 1 end
- if t.xreg and t.xreg > 7 then rex = rex + 2 end
- if s > 7 then rex = rex + 4 end
- if needrex then rex = rex + 16 end
- wputop(szov, opcode, rex); opcode = nil
- local imark = sub(pat, -1) -- Force a mark (ugly).
- -- Put ModRM/SIB with regno/last digit as spare.
- wputmrmsib(t, imark, s, addin and addin.vreg)
- addin = nil
- else
- if opcode then -- Flush opcode.
- if szov == "q" and rex == 0 then rex = rex + 8 end
- if needrex then rex = rex + 16 end
- if addin and addin.reg == -1 then
- wputop(szov, opcode - 7, rex)
- waction("VREG", addin.vreg); wputxb(0)
- else
- if addin and addin.reg > 7 then rex = rex + 1 end
- wputop(szov, opcode, rex)
- end
- opcode = nil
- end
- if c == "|" then break end
- if c == "o" then -- Offset (pure 32 bit displacement).
- wputdarg(args[1].disp); if narg < 2 then narg = 2 end
- elseif c == "O" then
- wputdarg(args[2].disp); narg = 3
- else
- -- Anything else is an immediate operand.
- local a = args[narg]
- narg = narg + 1
- local mode, imm = a.mode, a.imm
- if mode == "iJ" and not match("iIJ", c) then
- werror("bad operand size for label")
- end
- if c == "S" then
- wputsbarg(imm)
- elseif c == "U" then
- wputbarg(imm)
- elseif c == "W" then
- wputwarg(imm)
- elseif c == "i" or c == "I" then
- if mode == "iJ" then
- wputlabel("IMM_", imm, 1)
- elseif mode == "iI" and c == "I" then
- waction(sz == "w" and "IMM_WB" or "IMM_DB", imm)
- else
- wputszarg(sz, imm)
- end
- elseif c == "J" then
- if mode == "iPJ" then
- waction("REL_A", imm) -- !x64 (secpos)
- else
- wputlabel("REL_", imm, 2)
- end
- else
- werror("bad char `"..c.."' in pattern `"..pat.."' for `"..op.."'")
- end
- end
- end
- end
-end
-
-------------------------------------------------------------------------------
-
--- Mapping of operand modes to short names. Suppress output with '#'.
-local map_modename = {
- r = "reg", R = "eax", C = "cl", x = "mem", m = "mrm", i = "imm",
- f = "stx", F = "st0", J = "lbl", ["1"] = "1",
- I = "#", S = "#", O = "#",
-}
-
--- Return a table/string showing all possible operand modes.
-local function templatehelp(template, nparams)
- if nparams == 0 then return "" end
- local t = {}
- for tm in gmatch(template, "[^%|]+") do
- local s = map_modename[sub(tm, 1, 1)]
- s = s..gsub(sub(tm, 2, nparams), ".", function(c)
- return ", "..map_modename[c]
- end)
- if not match(s, "#") then t[#t+1] = s end
- end
- return t
-end
-
--- Match operand modes against mode match part of template.
-local function matchtm(tm, args)
- for i=1,#args do
- if not match(args[i].mode, sub(tm, i, i)) then return end
- end
- return true
-end
-
--- Handle opcodes defined with template strings.
-map_op[".template__"] = function(params, template, nparams)
- if not params then return templatehelp(template, nparams) end
- local args = {}
-
- -- Zero-operand opcodes have no match part.
- if #params == 0 then
- dopattern(template, args, "d", params.op, nil)
- return
- end
-
- -- Determine common operand size (coerce undefined size) or flag as mixed.
- local sz, szmix, needrex
- for i,p in ipairs(params) do
- args[i] = parseoperand(p)
- local nsz = args[i].opsize
- if nsz then
- if sz and sz ~= nsz then szmix = true else sz = nsz end
- end
- local nrex = args[i].needrex
- if nrex ~= nil then
- if needrex == nil then
- needrex = nrex
- elseif needrex ~= nrex then
- werror("bad mix of byte-addressable registers")
- end
- end
- end
-
- -- Try all match:pattern pairs (separated by '|').
- local gotmatch, lastpat
- for tm in gmatch(template, "[^%|]+") do
- -- Split off size match (starts after mode match) and pattern string.
- local szm, pat = match(tm, "^(.-):(.*)$", #args+1)
- if pat == "" then pat = lastpat else lastpat = pat end
- if matchtm(tm, args) then
- local prefix = sub(szm, 1, 1)
- if prefix == "/" then -- Match both operand sizes.
- if args[1].opsize == sub(szm, 2, 2) and
- args[2].opsize == sub(szm, 3, 3) then
- dopattern(pat, args, sz, params.op, needrex) -- Process pattern.
- return
- end
- else -- Match common operand size.
- local szp = sz
- if szm == "" then szm = x64 and "qdwb" or "dwb" end -- Default sizes.
- if prefix == "1" then szp = args[1].opsize; szmix = nil
- elseif prefix == "2" then szp = args[2].opsize; szmix = nil end
- if not szmix and (prefix == "." or match(szm, szp or "#")) then
- dopattern(pat, args, szp, params.op, needrex) -- Process pattern.
- return
- end
- end
- gotmatch = true
- end
- end
-
- local msg = "bad operand mode"
- if gotmatch then
- if szmix then
- msg = "mixed operand size"
- else
- msg = sz and "bad operand size" or "missing operand size"
- end
- end
-
- werror(msg.." in `"..opmodestr(params.op, args).."'")
-end
-
-------------------------------------------------------------------------------
-
--- x64-specific opcode for 64 bit immediates and displacements.
-if x64 then
- function map_op.mov64_2(params)
- if not params then return { "reg, imm", "reg, [disp]", "[disp], reg" } end
- if secpos+2 > maxsecpos then wflush() end
- local opcode, op64, sz, rex, vreg
- local op64 = match(params[1], "^%[%s*(.-)%s*%]$")
- if op64 then
- local a = parseoperand(params[2])
- if a.mode ~= "rmR" then werror("bad operand mode") end
- sz = a.opsize
- rex = sz == "q" and 8 or 0
- opcode = 0xa3
- else
- op64 = match(params[2], "^%[%s*(.-)%s*%]$")
- local a = parseoperand(params[1])
- if op64 then
- if a.mode ~= "rmR" then werror("bad operand mode") end
- sz = a.opsize
- rex = sz == "q" and 8 or 0
- opcode = 0xa1
- else
- if sub(a.mode, 1, 1) ~= "r" or a.opsize ~= "q" then
- werror("bad operand mode")
- end
- op64 = params[2]
- if a.reg == -1 then
- vreg = a.vreg
- opcode = 0xb8
- else
- opcode = 0xb8 + band(a.reg, 7)
- end
- rex = a.reg > 7 and 9 or 8
- end
- end
- wputop(sz, opcode, rex)
- if vreg then waction("VREG", vreg); wputxb(0) end
- waction("IMM_D", format("(unsigned int)(%s)", op64))
- waction("IMM_D", format("(unsigned int)((%s)>>32)", op64))
- end
-end
-
-------------------------------------------------------------------------------
-
--- Pseudo-opcodes for data storage.
-local function op_data(params)
- if not params then return "imm..." end
- local sz = sub(params.op, 2, 2)
- if sz == "a" then sz = addrsize end
- for _,p in ipairs(params) do
- local a = parseoperand(p)
- if sub(a.mode, 1, 1) ~= "i" or (a.opsize and a.opsize ~= sz) then
- werror("bad mode or size in `"..p.."'")
- end
- if a.mode == "iJ" then
- wputlabel("IMM_", a.imm, 1)
- else
- wputszarg(sz, a.imm)
- end
- if secpos+2 > maxsecpos then wflush() end
- end
-end
-
-map_op[".byte_*"] = op_data
-map_op[".sbyte_*"] = op_data
-map_op[".word_*"] = op_data
-map_op[".dword_*"] = op_data
-map_op[".aword_*"] = op_data
-
-------------------------------------------------------------------------------
-
--- Pseudo-opcode to mark the position where the action list is to be emitted.
-map_op[".actionlist_1"] = function(params)
- if not params then return "cvar" end
- local name = params[1] -- No syntax check. You get to keep the pieces.
- wline(function(out) writeactions(out, name) end)
-end
-
--- Pseudo-opcode to mark the position where the global enum is to be emitted.
-map_op[".globals_1"] = function(params)
- if not params then return "prefix" end
- local prefix = params[1] -- No syntax check. You get to keep the pieces.
- wline(function(out) writeglobals(out, prefix) end)
-end
-
--- Pseudo-opcode to mark the position where the global names are to be emitted.
-map_op[".globalnames_1"] = function(params)
- if not params then return "cvar" end
- local name = params[1] -- No syntax check. You get to keep the pieces.
- wline(function(out) writeglobalnames(out, name) end)
-end
-
--- Pseudo-opcode to mark the position where the extern names are to be emitted.
-map_op[".externnames_1"] = function(params)
- if not params then return "cvar" end
- local name = params[1] -- No syntax check. You get to keep the pieces.
- wline(function(out) writeexternnames(out, name) end)
-end
-
-------------------------------------------------------------------------------
-
--- Label pseudo-opcode (converted from trailing colon form).
-map_op[".label_2"] = function(params)
- if not params then return "[1-9] | ->global | =>pcexpr [, addr]" end
- if secpos+2 > maxsecpos then wflush() end
- local a = parseoperand(params[1])
- local mode, imm = a.mode, a.imm
- if type(imm) == "number" and (mode == "iJ" or (imm >= 1 and imm <= 9)) then
- -- Local label (1: ... 9:) or global label (->global:).
- waction("LABEL_LG", nil, 1)
- wputxb(imm)
- elseif mode == "iJ" then
- -- PC label (=>pcexpr:).
- waction("LABEL_PC", imm)
- else
- werror("bad label definition")
- end
- -- SETLABEL must immediately follow LABEL_LG/LABEL_PC.
- local addr = params[2]
- if addr then
- local a = parseoperand(addr)
- if a.mode == "iPJ" then
- waction("SETLABEL", a.imm)
- else
- werror("bad label assignment")
- end
- end
-end
-map_op[".label_1"] = map_op[".label_2"]
-
-------------------------------------------------------------------------------
-
--- Alignment pseudo-opcode.
-map_op[".align_1"] = function(params)
- if not params then return "numpow2" end
- if secpos+1 > maxsecpos then wflush() end
- local align = tonumber(params[1]) or map_opsizenum[map_opsize[params[1]]]
- if align then
- local x = align
- -- Must be a power of 2 in the range (2 ... 256).
- for i=1,8 do
- x = x / 2
- if x == 1 then
- waction("ALIGN", nil, 1)
- wputxb(align-1) -- Action byte is 2**n-1.
- return
- end
- end
- end
- werror("bad alignment")
-end
-
--- Spacing pseudo-opcode.
-map_op[".space_2"] = function(params)
- if not params then return "num [, filler]" end
- if secpos+1 > maxsecpos then wflush() end
- waction("SPACE", params[1])
- local fill = params[2]
- if fill then
- fill = tonumber(fill)
- if not fill or fill < 0 or fill > 255 then werror("bad filler") end
- end
- wputxb(fill or 0)
-end
-map_op[".space_1"] = map_op[".space_2"]
-
-------------------------------------------------------------------------------
-
--- Pseudo-opcode for (primitive) type definitions (map to C types).
-map_op[".type_3"] = function(params, nparams)
- if not params then
- return nparams == 2 and "name, ctype" or "name, ctype, reg"
- end
- local name, ctype, reg = params[1], params[2], params[3]
- if not match(name, "^[%a_][%w_]*$") then
- werror("bad type name `"..name.."'")
- end
- local tp = map_type[name]
- if tp then
- werror("duplicate type `"..name.."'")
- end
- if reg and not map_reg_valid_base[reg] then
- werror("bad base register `"..(map_reg_rev[reg] or reg).."'")
- end
- -- Add #type to defines. A bit unclean to put it in map_archdef.
- map_archdef["#"..name] = "sizeof("..ctype..")"
- -- Add new type and emit shortcut define.
- local num = ctypenum + 1
- map_type[name] = {
- ctype = ctype,
- ctypefmt = format("Dt%X(%%s)", num),
- reg = reg,
- }
- wline(format("#define Dt%X(_V) (int)(ptrdiff_t)&(((%s *)0)_V)", num, ctype))
- ctypenum = num
-end
-map_op[".type_2"] = map_op[".type_3"]
-
--- Dump type definitions.
-local function dumptypes(out, lvl)
- local t = {}
- for name in pairs(map_type) do t[#t+1] = name end
- sort(t)
- out:write("Type definitions:\n")
- for _,name in ipairs(t) do
- local tp = map_type[name]
- local reg = tp.reg and map_reg_rev[tp.reg] or ""
- out:write(format(" %-20s %-20s %s\n", name, tp.ctype, reg))
- end
- out:write("\n")
-end
-
-------------------------------------------------------------------------------
-
--- Set the current section.
-function _M.section(num)
- waction("SECTION")
- wputxb(num)
- wflush(true) -- SECTION is a terminal action.
-end
-
-------------------------------------------------------------------------------
-
--- Dump architecture description.
-function _M.dumparch(out)
- out:write(format("DynASM %s version %s, released %s\n\n",
- _info.arch, _info.version, _info.release))
- dumpregs(out)
- dumpactions(out)
-end
-
--- Dump all user defined elements.
-function _M.dumpdef(out, lvl)
- dumptypes(out, lvl)
- dumpglobals(out, lvl)
- dumpexterns(out, lvl)
-end
-
-------------------------------------------------------------------------------
-
--- Pass callbacks from/to the DynASM core.
-function _M.passcb(wl, we, wf, ww)
- wline, werror, wfatal, wwarn = wl, we, wf, ww
- return wflush
-end
-
--- Setup the arch-specific module.
-function _M.setup(arch, opt)
- g_arch, g_opt = arch, opt
-end
-
--- Merge the core maps and the arch-specific maps.
-function _M.mergemaps(map_coreop, map_def)
- setmetatable(map_op, { __index = map_coreop })
- setmetatable(map_def, { __index = map_archdef })
- return map_op, map_def
-end
-
-return _M
-
-------------------------------------------------------------------------------
-
diff --git a/core/src/luajit/dynasm/dynasm.lua b/core/src/luajit/dynasm/dynasm.lua
deleted file mode 100644
index fffda7513..000000000
--- a/core/src/luajit/dynasm/dynasm.lua
+++ /dev/null
@@ -1,1094 +0,0 @@
-------------------------------------------------------------------------------
--- DynASM. A dynamic assembler for code generation engines.
--- Originally designed and implemented for LuaJIT.
---
--- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
--- See below for full copyright notice.
-------------------------------------------------------------------------------
-
--- Application information.
-local _info = {
- name = "DynASM",
- description = "A dynamic assembler for code generation engines",
- version = "1.3.0",
- vernum = 10300,
- release = "2011-05-05",
- author = "Mike Pall",
- url = "http://luajit.org/dynasm.html",
- license = "MIT",
- copyright = [[
-Copyright (C) 2005-2015 Mike Pall. All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-[ MIT license: http://www.opensource.org/licenses/mit-license.php ]
-]],
-}
-
--- Cache library functions.
-local type, pairs, ipairs = type, pairs, ipairs
-local pcall, error, assert = pcall, error, assert
-local _s = string
-local sub, match, gmatch, gsub = _s.sub, _s.match, _s.gmatch, _s.gsub
-local format, rep, upper = _s.format, _s.rep, _s.upper
-local _t = table
-local insert, remove, concat, sort = _t.insert, _t.remove, _t.concat, _t.sort
-local exit = os.exit
-local io = io
-local stdin, stdout, stderr = io.stdin, io.stdout, io.stderr
-
-------------------------------------------------------------------------------
-
--- Program options.
-local g_opt = {}
-
--- Global state for current file.
-local g_fname, g_curline, g_indent, g_lineno, g_synclineno, g_arch
-local g_errcount = 0
-
--- Write buffer for output file.
-local g_wbuffer, g_capbuffer
-
-------------------------------------------------------------------------------
-
--- Write an output line (or callback function) to the buffer.
-local function wline(line, needindent)
- local buf = g_capbuffer or g_wbuffer
- buf[#buf+1] = needindent and g_indent..line or line
- g_synclineno = g_synclineno + 1
-end
-
--- Write assembler line as a comment, if requestd.
-local function wcomment(aline)
- if g_opt.comment then
- wline(g_opt.comment..aline..g_opt.endcomment, true)
- end
-end
-
--- Resync CPP line numbers.
-local function wsync()
- if g_synclineno ~= g_lineno and g_opt.cpp then
- wline("#line "..g_lineno..' "'..g_fname..'"')
- g_synclineno = g_lineno
- end
-end
-
--- Dummy action flush function. Replaced with arch-specific function later.
-local function wflush(term)
-end
-
--- Dump all buffered output lines.
-local function wdumplines(out, buf)
- for _,line in ipairs(buf) do
- if type(line) == "string" then
- assert(out:write(line, "\n"))
- else
- -- Special callback to dynamically insert lines after end of processing.
- line(out)
- end
- end
-end
-
-------------------------------------------------------------------------------
-
--- Emit an error. Processing continues with next statement.
-local function werror(msg)
- error(format("%s:%s: error: %s:\n%s", g_fname, g_lineno, msg, g_curline), 0)
-end
-
--- Emit a fatal error. Processing stops.
-local function wfatal(msg)
- g_errcount = "fatal"
- werror(msg)
-end
-
--- Print a warning. Processing continues.
-local function wwarn(msg)
- stderr:write(format("%s:%s: warning: %s:\n%s\n",
- g_fname, g_lineno, msg, g_curline))
-end
-
--- Print caught error message. But suppress excessive errors.
-local function wprinterr(...)
- if type(g_errcount) == "number" then
- -- Regular error.
- g_errcount = g_errcount + 1
- if g_errcount < 21 then -- Seems to be a reasonable limit.
- stderr:write(...)
- elseif g_errcount == 21 then
- stderr:write(g_fname,
- ":*: warning: too many errors (suppressed further messages).\n")
- end
- else
- -- Fatal error.
- stderr:write(...)
- return true -- Stop processing.
- end
-end
-
-------------------------------------------------------------------------------
-
--- Map holding all option handlers.
-local opt_map = {}
-local opt_current
-
--- Print error and exit with error status.
-local function opterror(...)
- stderr:write("dynasm.lua: ERROR: ", ...)
- stderr:write("\n")
- exit(1)
-end
-
--- Get option parameter.
-local function optparam(args)
- local argn = args.argn
- local p = args[argn]
- if not p then
- opterror("missing parameter for option `", opt_current, "'.")
- end
- args.argn = argn + 1
- return p
-end
-
-------------------------------------------------------------------------------
-
--- Core pseudo-opcodes.
-local map_coreop = {}
--- Dummy opcode map. Replaced by arch-specific map.
-local map_op = {}
-
--- Forward declarations.
-local dostmt
-local readfile
-
-------------------------------------------------------------------------------
-
--- Map for defines (initially empty, chains to arch-specific map).
-local map_def = {}
-
--- Pseudo-opcode to define a substitution.
-map_coreop[".define_2"] = function(params, nparams)
- if not params then return nparams == 1 and "name" or "name, subst" end
- local name, def = params[1], params[2] or "1"
- if not match(name, "^[%a_][%w_]*$") then werror("bad or duplicate define") end
- map_def[name] = def
-end
-map_coreop[".define_1"] = map_coreop[".define_2"]
-
--- Define a substitution on the command line.
-function opt_map.D(args)
- local namesubst = optparam(args)
- local name, subst = match(namesubst, "^([%a_][%w_]*)=(.*)$")
- if name then
- map_def[name] = subst
- elseif match(namesubst, "^[%a_][%w_]*$") then
- map_def[namesubst] = "1"
- else
- opterror("bad define")
- end
-end
-
--- Undefine a substitution on the command line.
-function opt_map.U(args)
- local name = optparam(args)
- if match(name, "^[%a_][%w_]*$") then
- map_def[name] = nil
- else
- opterror("bad define")
- end
-end
-
--- Helper for definesubst.
-local gotsubst
-
-local function definesubst_one(word)
- local subst = map_def[word]
- if subst then gotsubst = word; return subst else return word end
-end
-
--- Iteratively substitute defines.
-local function definesubst(stmt)
- -- Limit number of iterations.
- for i=1,100 do
- gotsubst = false
- stmt = gsub(stmt, "#?[%w_]+", definesubst_one)
- if not gotsubst then break end
- end
- if gotsubst then wfatal("recursive define involving `"..gotsubst.."'") end
- return stmt
-end
-
--- Dump all defines.
-local function dumpdefines(out, lvl)
- local t = {}
- for name in pairs(map_def) do
- t[#t+1] = name
- end
- sort(t)
- out:write("Defines:\n")
- for _,name in ipairs(t) do
- local subst = map_def[name]
- if g_arch then subst = g_arch.revdef(subst) end
- out:write(format(" %-20s %s\n", name, subst))
- end
- out:write("\n")
-end
-
-------------------------------------------------------------------------------
-
--- Support variables for conditional assembly.
-local condlevel = 0
-local condstack = {}
-
--- Evaluate condition with a Lua expression. Substitutions already performed.
-local function cond_eval(cond)
- local func, err
- if setfenv then
- func, err = loadstring("return "..cond, "=expr")
- else
- -- No globals. All unknown identifiers evaluate to nil.
- func, err = load("return "..cond, "=expr", "t", {})
- end
- if func then
- if setfenv then
- setfenv(func, {}) -- No globals. All unknown identifiers evaluate to nil.
- end
- local ok, res = pcall(func)
- if ok then
- if res == 0 then return false end -- Oh well.
- return not not res
- end
- err = res
- end
- wfatal("bad condition: "..err)
-end
-
--- Skip statements until next conditional pseudo-opcode at the same level.
-local function stmtskip()
- local dostmt_save = dostmt
- local lvl = 0
- dostmt = function(stmt)
- local op = match(stmt, "^%s*(%S+)")
- if op == ".if" then
- lvl = lvl + 1
- elseif lvl ~= 0 then
- if op == ".endif" then lvl = lvl - 1 end
- elseif op == ".elif" or op == ".else" or op == ".endif" then
- dostmt = dostmt_save
- dostmt(stmt)
- end
- end
-end
-
--- Pseudo-opcodes for conditional assembly.
-map_coreop[".if_1"] = function(params)
- if not params then return "condition" end
- local lvl = condlevel + 1
- local res = cond_eval(params[1])
- condlevel = lvl
- condstack[lvl] = res
- if not res then stmtskip() end
-end
-
-map_coreop[".elif_1"] = function(params)
- if not params then return "condition" end
- if condlevel == 0 then wfatal(".elif without .if") end
- local lvl = condlevel
- local res = condstack[lvl]
- if res then
- if res == "else" then wfatal(".elif after .else") end
- else
- res = cond_eval(params[1])
- if res then
- condstack[lvl] = res
- return
- end
- end
- stmtskip()
-end
-
-map_coreop[".else_0"] = function(params)
- if condlevel == 0 then wfatal(".else without .if") end
- local lvl = condlevel
- local res = condstack[lvl]
- condstack[lvl] = "else"
- if res then
- if res == "else" then wfatal(".else after .else") end
- stmtskip()
- end
-end
-
-map_coreop[".endif_0"] = function(params)
- local lvl = condlevel
- if lvl == 0 then wfatal(".endif without .if") end
- condlevel = lvl - 1
-end
-
--- Check for unfinished conditionals.
-local function checkconds()
- if g_errcount ~= "fatal" and condlevel ~= 0 then
- wprinterr(g_fname, ":*: error: unbalanced conditional\n")
- end
-end
-
-------------------------------------------------------------------------------
-
--- Search for a file in the given path and open it for reading.
-local function pathopen(path, name)
- local dirsep = package and match(package.path, "\\") and "\\" or "/"
- for _,p in ipairs(path) do
- local fullname = p == "" and name or p..dirsep..name
- local fin = io.open(fullname, "r")
- if fin then
- g_fname = fullname
- return fin
- end
- end
-end
-
--- Include a file.
-map_coreop[".include_1"] = function(params)
- if not params then return "filename" end
- local name = params[1]
- -- Save state. Ugly, I know. but upvalues are fast.
- local gf, gl, gcl, gi = g_fname, g_lineno, g_curline, g_indent
- -- Read the included file.
- local fatal = readfile(pathopen(g_opt.include, name) or
- wfatal("include file `"..name.."' not found"))
- -- Restore state.
- g_synclineno = -1
- g_fname, g_lineno, g_curline, g_indent = gf, gl, gcl, gi
- if fatal then wfatal("in include file") end
-end
-
--- Make .include and conditionals initially available, too.
-map_op[".include_1"] = map_coreop[".include_1"]
-map_op[".if_1"] = map_coreop[".if_1"]
-map_op[".elif_1"] = map_coreop[".elif_1"]
-map_op[".else_0"] = map_coreop[".else_0"]
-map_op[".endif_0"] = map_coreop[".endif_0"]
-
-------------------------------------------------------------------------------
-
--- Support variables for macros.
-local mac_capture, mac_lineno, mac_name
-local mac_active = {}
-local mac_list = {}
-
--- Pseudo-opcode to define a macro.
-map_coreop[".macro_*"] = function(mparams)
- if not mparams then return "name [, params...]" end
- -- Split off and validate macro name.
- local name = remove(mparams, 1)
- if not name then werror("missing macro name") end
- if not (match(name, "^[%a_][%w_%.]*$") or match(name, "^%.[%w_%.]*$")) then
- wfatal("bad macro name `"..name.."'")
- end
- -- Validate macro parameter names.
- local mdup = {}
- for _,mp in ipairs(mparams) do
- if not match(mp, "^[%a_][%w_]*$") then
- wfatal("bad macro parameter name `"..mp.."'")
- end
- if mdup[mp] then wfatal("duplicate macro parameter name `"..mp.."'") end
- mdup[mp] = true
- end
- -- Check for duplicate or recursive macro definitions.
- local opname = name.."_"..#mparams
- if map_op[opname] or map_op[name.."_*"] then
- wfatal("duplicate macro `"..name.."' ("..#mparams.." parameters)")
- end
- if mac_capture then wfatal("recursive macro definition") end
-
- -- Enable statement capture.
- local lines = {}
- mac_lineno = g_lineno
- mac_name = name
- mac_capture = function(stmt) -- Statement capture function.
- -- Stop macro definition with .endmacro pseudo-opcode.
- if not match(stmt, "^%s*.endmacro%s*$") then
- lines[#lines+1] = stmt
- return
- end
- mac_capture = nil
- mac_lineno = nil
- mac_name = nil
- mac_list[#mac_list+1] = opname
- -- Add macro-op definition.
- map_op[opname] = function(params)
- if not params then return mparams, lines end
- -- Protect against recursive macro invocation.
- if mac_active[opname] then wfatal("recursive macro invocation") end
- mac_active[opname] = true
- -- Setup substitution map.
- local subst = {}
- for i,mp in ipairs(mparams) do subst[mp] = params[i] end
- local mcom
- if g_opt.maccomment and g_opt.comment then
- mcom = " MACRO "..name.." ("..#mparams..")"
- wcomment("{"..mcom)
- end
- -- Loop through all captured statements
- for _,stmt in ipairs(lines) do
- -- Substitute macro parameters.
- local st = gsub(stmt, "[%w_]+", subst)
- st = definesubst(st)
- st = gsub(st, "%s*%.%.%s*", "") -- Token paste a..b.
- if mcom and sub(st, 1, 1) ~= "|" then wcomment(st) end
- -- Emit statement. Use a protected call for better diagnostics.
- local ok, err = pcall(dostmt, st)
- if not ok then
- -- Add the captured statement to the error.
- wprinterr(err, "\n", g_indent, "| ", stmt,
- "\t[MACRO ", name, " (", #mparams, ")]\n")
- end
- end
- if mcom then wcomment("}"..mcom) end
- mac_active[opname] = nil
- end
- end
-end
-
--- An .endmacro pseudo-opcode outside of a macro definition is an error.
-map_coreop[".endmacro_0"] = function(params)
- wfatal(".endmacro without .macro")
-end
-
--- Dump all macros and their contents (with -PP only).
-local function dumpmacros(out, lvl)
- sort(mac_list)
- out:write("Macros:\n")
- for _,opname in ipairs(mac_list) do
- local name = sub(opname, 1, -3)
- local params, lines = map_op[opname]()
- out:write(format(" %-20s %s\n", name, concat(params, ", ")))
- if lvl > 1 then
- for _,line in ipairs(lines) do
- out:write(" |", line, "\n")
- end
- out:write("\n")
- end
- end
- out:write("\n")
-end
-
--- Check for unfinished macro definitions.
-local function checkmacros()
- if mac_capture then
- wprinterr(g_fname, ":", mac_lineno,
- ": error: unfinished .macro `", mac_name ,"'\n")
- end
-end
-
-------------------------------------------------------------------------------
-
--- Support variables for captures.
-local cap_lineno, cap_name
-local cap_buffers = {}
-local cap_used = {}
-
--- Start a capture.
-map_coreop[".capture_1"] = function(params)
- if not params then return "name" end
- wflush()
- local name = params[1]
- if not match(name, "^[%a_][%w_]*$") then
- wfatal("bad capture name `"..name.."'")
- end
- if cap_name then
- wfatal("already capturing to `"..cap_name.."' since line "..cap_lineno)
- end
- cap_name = name
- cap_lineno = g_lineno
- -- Create or continue a capture buffer and start the output line capture.
- local buf = cap_buffers[name]
- if not buf then buf = {}; cap_buffers[name] = buf end
- g_capbuffer = buf
- g_synclineno = 0
-end
-
--- Stop a capture.
-map_coreop[".endcapture_0"] = function(params)
- wflush()
- if not cap_name then wfatal(".endcapture without a valid .capture") end
- cap_name = nil
- cap_lineno = nil
- g_capbuffer = nil
- g_synclineno = 0
-end
-
--- Dump a capture buffer.
-map_coreop[".dumpcapture_1"] = function(params)
- if not params then return "name" end
- wflush()
- local name = params[1]
- if not match(name, "^[%a_][%w_]*$") then
- wfatal("bad capture name `"..name.."'")
- end
- cap_used[name] = true
- wline(function(out)
- local buf = cap_buffers[name]
- if buf then wdumplines(out, buf) end
- end)
- g_synclineno = 0
-end
-
--- Dump all captures and their buffers (with -PP only).
-local function dumpcaptures(out, lvl)
- out:write("Captures:\n")
- for name,buf in pairs(cap_buffers) do
- out:write(format(" %-20s %4s)\n", name, "("..#buf))
- if lvl > 1 then
- local bar = rep("=", 76)
- out:write(" ", bar, "\n")
- for _,line in ipairs(buf) do
- out:write(" ", line, "\n")
- end
- out:write(" ", bar, "\n\n")
- end
- end
- out:write("\n")
-end
-
--- Check for unfinished or unused captures.
-local function checkcaptures()
- if cap_name then
- wprinterr(g_fname, ":", cap_lineno,
- ": error: unfinished .capture `", cap_name,"'\n")
- return
- end
- for name in pairs(cap_buffers) do
- if not cap_used[name] then
- wprinterr(g_fname, ":*: error: missing .dumpcapture ", name ,"\n")
- end
- end
-end
-
-------------------------------------------------------------------------------
-
--- Sections names.
-local map_sections = {}
-
--- Pseudo-opcode to define code sections.
--- TODO: Data sections, BSS sections. Needs extra C code and API.
-map_coreop[".section_*"] = function(params)
- if not params then return "name..." end
- if #map_sections > 0 then werror("duplicate section definition") end
- wflush()
- for sn,name in ipairs(params) do
- local opname = "."..name.."_0"
- if not match(name, "^[%a][%w_]*$") or
- map_op[opname] or map_op["."..name.."_*"] then
- werror("bad section name `"..name.."'")
- end
- map_sections[#map_sections+1] = name
- wline(format("#define DASM_SECTION_%s\t%d", upper(name), sn-1))
- map_op[opname] = function(params) g_arch.section(sn-1) end
- end
- wline(format("#define DASM_MAXSECTION\t\t%d", #map_sections))
-end
-
--- Dump all sections.
-local function dumpsections(out, lvl)
- out:write("Sections:\n")
- for _,name in ipairs(map_sections) do
- out:write(format(" %s\n", name))
- end
- out:write("\n")
-end
-
-------------------------------------------------------------------------------
-
--- Replacement for customized Lua, which lacks the package library.
-local prefix = ""
-if not require then
- function require(name)
- local fp = assert(io.open(prefix..name..".lua"))
- local s = fp:read("*a")
- assert(fp:close())
- return assert(loadstring(s, "@"..name..".lua"))()
- end
-end
-
--- Load architecture-specific module.
-local function loadarch(arch)
- if not match(arch, "^[%w_]+$") then return "bad arch name" end
- local ok, m_arch = pcall(require, "dasm_"..arch)
- if not ok then return "cannot load module: "..m_arch end
- g_arch = m_arch
- wflush = m_arch.passcb(wline, werror, wfatal, wwarn)
- m_arch.setup(arch, g_opt)
- map_op, map_def = m_arch.mergemaps(map_coreop, map_def)
-end
-
--- Dump architecture description.
-function opt_map.dumparch(args)
- local name = optparam(args)
- if not g_arch then
- local err = loadarch(name)
- if err then opterror(err) end
- end
-
- local t = {}
- for name in pairs(map_coreop) do t[#t+1] = name end
- for name in pairs(map_op) do t[#t+1] = name end
- sort(t)
-
- local out = stdout
- local _arch = g_arch._info
- out:write(format("%s version %s, released %s, %s\n",
- _info.name, _info.version, _info.release, _info.url))
- g_arch.dumparch(out)
-
- local pseudo = true
- out:write("Pseudo-Opcodes:\n")
- for _,sname in ipairs(t) do
- local name, nparam = match(sname, "^(.+)_([0-9%*])$")
- if name then
- if pseudo and sub(name, 1, 1) ~= "." then
- out:write("\nOpcodes:\n")
- pseudo = false
- end
- local f = map_op[sname]
- local s
- if nparam ~= "*" then nparam = nparam + 0 end
- if nparam == 0 then
- s = ""
- elseif type(f) == "string" then
- s = map_op[".template__"](nil, f, nparam)
- else
- s = f(nil, nparam)
- end
- if type(s) == "table" then
- for _,s2 in ipairs(s) do
- out:write(format(" %-12s %s\n", name, s2))
- end
- else
- out:write(format(" %-12s %s\n", name, s))
- end
- end
- end
- out:write("\n")
- exit(0)
-end
-
--- Pseudo-opcode to set the architecture.
--- Only initially available (map_op is replaced when called).
-map_op[".arch_1"] = function(params)
- if not params then return "name" end
- local err = loadarch(params[1])
- if err then wfatal(err) end
- wline(format("#if DASM_VERSION != %d", _info.vernum))
- wline('#error "Version mismatch between DynASM and included encoding engine"')
- wline("#endif")
-end
-
--- Dummy .arch pseudo-opcode to improve the error report.
-map_coreop[".arch_1"] = function(params)
- if not params then return "name" end
- wfatal("duplicate .arch statement")
-end
-
-------------------------------------------------------------------------------
-
--- Dummy pseudo-opcode. Don't confuse '.nop' with 'nop'.
-map_coreop[".nop_*"] = function(params)
- if not params then return "[ignored...]" end
-end
-
--- Pseudo-opcodes to raise errors.
-map_coreop[".error_1"] = function(params)
- if not params then return "message" end
- werror(params[1])
-end
-
-map_coreop[".fatal_1"] = function(params)
- if not params then return "message" end
- wfatal(params[1])
-end
-
--- Dump all user defined elements.
-local function dumpdef(out)
- local lvl = g_opt.dumpdef
- if lvl == 0 then return end
- dumpsections(out, lvl)
- dumpdefines(out, lvl)
- if g_arch then g_arch.dumpdef(out, lvl) end
- dumpmacros(out, lvl)
- dumpcaptures(out, lvl)
-end
-
-------------------------------------------------------------------------------
-
--- Helper for splitstmt.
-local splitlvl
-
-local function splitstmt_one(c)
- if c == "(" then
- splitlvl = ")"..splitlvl
- elseif c == "[" then
- splitlvl = "]"..splitlvl
- elseif c == "{" then
- splitlvl = "}"..splitlvl
- elseif c == ")" or c == "]" or c == "}" then
- if sub(splitlvl, 1, 1) ~= c then werror("unbalanced (), [] or {}") end
- splitlvl = sub(splitlvl, 2)
- elseif splitlvl == "" then
- return " \0 "
- end
- return c
-end
-
--- Split statement into (pseudo-)opcode and params.
-local function splitstmt(stmt)
- -- Convert label with trailing-colon into .label statement.
- local label = match(stmt, "^%s*(.+):%s*$")
- if label then return ".label", {label} end
-
- -- Split at commas and equal signs, but obey parentheses and brackets.
- splitlvl = ""
- stmt = gsub(stmt, "[,%(%)%[%]{}]", splitstmt_one)
- if splitlvl ~= "" then werror("unbalanced () or []") end
-
- -- Split off opcode.
- local op, other = match(stmt, "^%s*([^%s%z]+)%s*(.*)$")
- if not op then werror("bad statement syntax") end
-
- -- Split parameters.
- local params = {}
- for p in gmatch(other, "%s*(%Z+)%z?") do
- params[#params+1] = gsub(p, "%s+$", "")
- end
- if #params > 16 then werror("too many parameters") end
-
- params.op = op
- return op, params
-end
-
--- Process a single statement.
-dostmt = function(stmt)
- -- Ignore empty statements.
- if match(stmt, "^%s*$") then return end
-
- -- Capture macro defs before substitution.
- if mac_capture then return mac_capture(stmt) end
- stmt = definesubst(stmt)
-
- -- Emit C code without parsing the line.
- if sub(stmt, 1, 1) == "|" then
- local tail = sub(stmt, 2)
- wflush()
- if sub(tail, 1, 2) == "//" then wcomment(tail) else wline(tail, true) end
- return
- end
-
- -- Split into (pseudo-)opcode and params.
- local op, params = splitstmt(stmt)
-
- -- Get opcode handler (matching # of parameters or generic handler).
- local f = map_op[op.."_"..#params] or map_op[op.."_*"]
- if not f then
- if not g_arch then wfatal("first statement must be .arch") end
- -- Improve error report.
- for i=0,9 do
- if map_op[op.."_"..i] then
- werror("wrong number of parameters for `"..op.."'")
- end
- end
- werror("unknown statement `"..op.."'")
- end
-
- -- Call opcode handler or special handler for template strings.
- if type(f) == "string" then
- map_op[".template__"](params, f)
- else
- f(params)
- end
-end
-
--- Process a single line.
-local function doline(line)
- if g_opt.flushline then wflush() end
-
- -- Assembler line?
- local indent, aline = match(line, "^(%s*)%|(.*)$")
- if not aline then
- -- No, plain C code line, need to flush first.
- wflush()
- wsync()
- wline(line, false)
- return
- end
-
- g_indent = indent -- Remember current line indentation.
-
- -- Emit C code (even from macros). Avoids echo and line parsing.
- if sub(aline, 1, 1) == "|" then
- if not mac_capture then
- wsync()
- elseif g_opt.comment then
- wsync()
- wcomment(aline)
- end
- dostmt(aline)
- return
- end
-
- -- Echo assembler line as a comment.
- if g_opt.comment then
- wsync()
- wcomment(aline)
- end
-
- -- Strip assembler comments.
- aline = gsub(aline, "//.*$", "")
-
- -- Split line into statements at semicolons.
- if match(aline, ";") then
- for stmt in gmatch(aline, "[^;]+") do dostmt(stmt) end
- else
- dostmt(aline)
- end
-end
-
-------------------------------------------------------------------------------
-
--- Write DynASM header.
-local function dasmhead(out)
- out:write(format([[
-/*
-** This file has been pre-processed with DynASM.
-** %s
-** DynASM version %s, DynASM %s version %s
-** DO NOT EDIT! The original file is in "%s".
-*/
-
-]], _info.url,
- _info.version, g_arch._info.arch, g_arch._info.version,
- g_fname))
-end
-
--- Read input file.
-readfile = function(fin)
- g_indent = ""
- g_lineno = 0
- g_synclineno = -1
-
- -- Process all lines.
- for line in fin:lines() do
- g_lineno = g_lineno + 1
- g_curline = line
- local ok, err = pcall(doline, line)
- if not ok and wprinterr(err, "\n") then return true end
- end
- wflush()
-
- -- Close input file.
- assert(fin == stdin or fin:close())
-end
-
--- Write output file.
-local function writefile(outfile)
- local fout
-
- -- Open output file.
- if outfile == nil or outfile == "-" then
- fout = stdout
- else
- fout = assert(io.open(outfile, "w"))
- end
-
- -- Write all buffered lines
- wdumplines(fout, g_wbuffer)
-
- -- Close output file.
- assert(fout == stdout or fout:close())
-
- -- Optionally dump definitions.
- dumpdef(fout == stdout and stderr or stdout)
-end
-
--- Translate an input file to an output file.
-local function translate(infile, outfile)
- g_wbuffer = {}
- g_indent = ""
- g_lineno = 0
- g_synclineno = -1
-
- -- Put header.
- wline(dasmhead)
-
- -- Read input file.
- local fin
- if infile == "-" then
- g_fname = "(stdin)"
- fin = stdin
- else
- g_fname = infile
- fin = assert(io.open(infile, "r"))
- end
- readfile(fin)
-
- -- Check for errors.
- if not g_arch then
- wprinterr(g_fname, ":*: error: missing .arch directive\n")
- end
- checkconds()
- checkmacros()
- checkcaptures()
-
- if g_errcount ~= 0 then
- stderr:write(g_fname, ":*: info: ", g_errcount, " error",
- (type(g_errcount) == "number" and g_errcount > 1) and "s" or "",
- " in input file -- no output file generated.\n")
- dumpdef(stderr)
- exit(1)
- end
-
- -- Write output file.
- writefile(outfile)
-end
-
-------------------------------------------------------------------------------
-
--- Print help text.
-function opt_map.help()
- stdout:write("DynASM -- ", _info.description, ".\n")
- stdout:write("DynASM ", _info.version, " ", _info.release, " ", _info.url, "\n")
- stdout:write[[
-
-Usage: dynasm [OPTION]... INFILE.dasc|-
-
- -h, --help Display this help text.
- -V, --version Display version and copyright information.
-
- -o, --outfile FILE Output file name (default is stdout).
- -I, --include DIR Add directory to the include search path.
-
- -c, --ccomment Use /* */ comments for assembler lines.
- -C, --cppcomment Use // comments for assembler lines (default).
- -N, --nocomment Suppress assembler lines in output.
- -M, --maccomment Show macro expansions as comments (default off).
-
- -L, --nolineno Suppress CPP line number information in output.
- -F, --flushline Flush action list for every line.
-
- -D NAME[=SUBST] Define a substitution.
- -U NAME Undefine a substitution.
-
- -P, --dumpdef Dump defines, macros, etc. Repeat for more output.
- -A, --dumparch ARCH Load architecture ARCH and dump description.
-]]
- exit(0)
-end
-
--- Print version information.
-function opt_map.version()
- stdout:write(format("%s version %s, released %s\n%s\n\n%s",
- _info.name, _info.version, _info.release, _info.url, _info.copyright))
- exit(0)
-end
-
--- Misc. options.
-function opt_map.outfile(args) g_opt.outfile = optparam(args) end
-function opt_map.include(args) insert(g_opt.include, 1, optparam(args)) end
-function opt_map.ccomment() g_opt.comment = "/*|"; g_opt.endcomment = " */" end
-function opt_map.cppcomment() g_opt.comment = "//|"; g_opt.endcomment = "" end
-function opt_map.nocomment() g_opt.comment = false end
-function opt_map.maccomment() g_opt.maccomment = true end
-function opt_map.nolineno() g_opt.cpp = false end
-function opt_map.flushline() g_opt.flushline = true end
-function opt_map.dumpdef() g_opt.dumpdef = g_opt.dumpdef + 1 end
-
-------------------------------------------------------------------------------
-
--- Short aliases for long options.
-local opt_alias = {
- h = "help", ["?"] = "help", V = "version",
- o = "outfile", I = "include",
- c = "ccomment", C = "cppcomment", N = "nocomment", M = "maccomment",
- L = "nolineno", F = "flushline",
- P = "dumpdef", A = "dumparch",
-}
-
--- Parse single option.
-local function parseopt(opt, args)
- opt_current = #opt == 1 and "-"..opt or "--"..opt
- local f = opt_map[opt] or opt_map[opt_alias[opt]]
- if not f then
- opterror("unrecognized option `", opt_current, "'. Try `--help'.\n")
- end
- f(args)
-end
-
--- Parse arguments.
-local function parseargs(args)
- -- Default options.
- g_opt.comment = "//|"
- g_opt.endcomment = ""
- g_opt.cpp = true
- g_opt.dumpdef = 0
- g_opt.include = { "" }
-
- -- Process all option arguments.
- args.argn = 1
- repeat
- local a = args[args.argn]
- if not a then break end
- local lopt, opt = match(a, "^%-(%-?)(.+)")
- if not opt then break end
- args.argn = args.argn + 1
- if lopt == "" then
- -- Loop through short options.
- for o in gmatch(opt, ".") do parseopt(o, args) end
- else
- -- Long option.
- parseopt(opt, args)
- end
- until false
-
- -- Check for proper number of arguments.
- local nargs = #args - args.argn + 1
- if nargs ~= 1 then
- if nargs == 0 then
- if g_opt.dumpdef > 0 then return dumpdef(stdout) end
- end
- opt_map.help()
- end
-
- -- Translate a single input file to a single output file
- -- TODO: Handle multiple files?
- translate(args[args.argn], g_opt.outfile)
-end
-
-------------------------------------------------------------------------------
-
--- Add the directory dynasm.lua resides in to the Lua module search path.
-local arg = arg
-if arg and arg[0] then
- prefix = match(arg[0], "^(.*[/\\])")
- if package and prefix then package.path = prefix.."?.lua;"..package.path end
-end
-
--- Start DynASM.
-parseargs{...}
-
-------------------------------------------------------------------------------
-
diff --git a/core/src/luajit/etc/luajit.1 b/core/src/luajit/etc/luajit.1
deleted file mode 100644
index fd38b0a92..000000000
--- a/core/src/luajit/etc/luajit.1
+++ /dev/null
@@ -1,88 +0,0 @@
-.TH luajit 1 "" "" "LuaJIT documentation"
-.SH NAME
-luajit \- Just-In-Time Compiler for the Lua Language
-\fB
-.SH SYNOPSIS
-.B luajit
-[\fIoptions\fR]... [\fIscript\fR [\fIargs\fR]...]
-.SH "WEB SITE"
-.IR http://luajit.org
-.SH DESCRIPTION
-.PP
-This is the command-line program to run Lua programs with \fBLuaJIT\fR.
-.PP
-\fBLuaJIT\fR is a just-in-time (JIT) compiler for the Lua language.
-The virtual machine (VM) is based on a fast interpreter combined with
-a trace compiler. It can significantly improve the performance of Lua programs.
-.PP
-\fBLuaJIT\fR is API\- and ABI-compatible with the VM of the standard
-Lua\ 5.1 interpreter. When embedding the VM into an application,
-the built library can be used as a drop-in replacement.
-.SH OPTIONS
-.TP
-.BI "\-e " chunk
-Run the given chunk of Lua code.
-.TP
-.BI "\-l " library
-Load the named library, just like \fBrequire("\fR\fIlibrary\fR\fB")\fR.
-.TP
-.BI "\-b " ...
-Save or list bytecode. Run without arguments to get help on options.
-.TP
-.BI "\-j " command
-Perform LuaJIT control command (optional space after \fB\-j\fR).
-.TP
-.BI "\-O" [opt]
-Control LuaJIT optimizations.
-.TP
-.B "\-i"
-Run in interactive mode.
-.TP
-.B "\-v"
-Show \fBLuaJIT\fR version.
-.TP
-.B "\-E"
-Ignore environment variables.
-.TP
-.B "\-\-"
-Stop processing options.
-.TP
-.B "\-"
-Read script from stdin instead.
-.PP
-After all options are processed, the given \fIscript\fR is run.
-The arguments are passed in the global \fIarg\fR table.
-.PP
-Interactive mode is only entered, if no \fIscript\fR and no \fB\-e\fR
-option is given. Interactive mode can be left with EOF (\fICtrl\-Z\fB).
-.SH EXAMPLES
-.TP
-luajit hello.lua world
-
-Prints "Hello world", assuming \fIhello.lua\fR contains:
-.br
- print("Hello", arg[1])
-.TP
-luajit \-e "local x=0; for i=1,1e9 do x=x+i end; print(x)"
-
-Calculates the sum of the numbers from 1 to 1000000000.
-.br
-And finishes in a reasonable amount of time, too.
-.TP
-luajit \-jv \-e "for i=1,10 do for j=1,10 do for k=1,100 do end end end"
-
-Runs some nested loops and shows the resulting traces.
-.SH COPYRIGHT
-.PP
-\fBLuaJIT\fR is Copyright \(co 2005-2015 Mike Pall.
-.br
-\fBLuaJIT\fR is open source software, released under the MIT license.
-.SH SEE ALSO
-.PP
-More details in the provided HTML docs or at:
-.IR http://luajit.org
-.br
-More about the Lua language can be found at:
-.IR http://lua.org/docs.html
-.PP
-lua(1)
diff --git a/core/src/luajit/etc/luajit.pc b/core/src/luajit/etc/luajit.pc
deleted file mode 100644
index a652b40d4..000000000
--- a/core/src/luajit/etc/luajit.pc
+++ /dev/null
@@ -1,25 +0,0 @@
-# Package information for LuaJIT to be used by pkg-config.
-majver=2
-minver=0
-relver=4
-version=${majver}.${minver}.${relver}
-abiver=5.1
-
-prefix=/usr/local
-multilib=lib
-exec_prefix=${prefix}
-libdir=${exec_prefix}/${multilib}
-libname=luajit-${abiver}
-includedir=${prefix}/include/luajit-${majver}.${minver}
-
-INSTALL_LMOD=${prefix}/share/lua/${abiver}
-INSTALL_CMOD=${prefix}/${multilib}/lua/${abiver}
-
-Name: LuaJIT
-Description: Just-in-time compiler for Lua
-URL: http://luajit.org
-Version: ${version}
-Requires:
-Libs: -L${libdir} -l${libname}
-Libs.private: -Wl,-E -lm -ldl
-Cflags: -I${includedir}
diff --git a/core/src/sv/test/CMakeLists.txt b/core/src/sv/test/CMakeLists.txt
deleted file mode 100644
index 89d4a0eec..000000000
--- a/core/src/sv/test/CMakeLists.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-add_executable(version version.c)
-target_link_libraries(version ${PROJECT_NAME})
-add_test(version version)
-
-add_executable(comp comp.c)
-target_link_libraries(comp ${PROJECT_NAME})
-add_test(comp comp)
-
-add_executable(range range.c)
-target_link_libraries(range ${PROJECT_NAME})
-add_test(range range)
-
-add_executable(match match.c)
-target_link_libraries(match ${PROJECT_NAME})
-add_test(match match)
-
-add_executable(utils utils.c)
-target_link_libraries(utils ${PROJECT_NAME})
-add_test(utils utils)
-
-add_executable(usage usage.c)
-target_link_libraries(usage ${PROJECT_NAME})
-add_test(usage usage)
-
-add_executable(semvers semvers.c)
-target_link_libraries(semvers ${PROJECT_NAME})
-add_test(semvers semvers)
diff --git a/core/src/sv/test/comp.c b/core/src/sv/test/comp.c
deleted file mode 100644
index faa68a500..000000000
--- a/core/src/sv/test/comp.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * This is free and unencumbered software released into the public domain.
- *
- * Anyone is free to copy, modify, publish, use, compile, sell, or
- * distribute this software, either in source code form or as a compiled
- * binary, for any purpose, commercial or non-commercial, and by any
- * means.
- *
- * In jurisdictions that recognize copyright laws, the author or authors
- * of this software dedicate any and all copyright interest in the
- * software to the public domain. We make this dedication for the benefit
- * of the public at large and to the detriment of our heirs and
- * successors. We intend this dedication to be an overt act of
- * relinquishment in perpetuity of all present and future rights to this
- * software under copyright law.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * For more information, please refer to <http://unlicense.org>
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "semver.h"
-
-#define STRNSIZE(s) (s), sizeof(s)-1
-
-int test_read(const char *expected, const char *str, size_t len) {
- unsigned slen;
- char buffer[1024];
- semver_comp_t comp = {0};
-
- printf("test: `%.*s`", (int) len, str);
- if (semver_compn(&comp, str, len)) {
- puts(" \tcouldn't parse");
- return 1;
- }
- slen = (unsigned) semver_comp_write(comp, buffer, 1024);
- printf(" \t=> \t`%.*s`", slen, buffer);
- if (memcmp(expected, buffer, (size_t) slen > len ? slen : len) != 0) {
- printf(" != `%s`\n", expected);
- semver_comp_dtor(&comp);
- return 1;
- }
- printf(" == `%s`\n", expected);
- semver_comp_dtor(&comp);
- return 0;
-}
-
-int test_and(const char *expected, const char *base_str, size_t base_len, const char *str, size_t len) {
- unsigned slen;
- char buffer[1024];
- semver_comp_t comp = {0};
-
- printf("test and: `%.*s`", (int) base_len, base_str);
- if (semver_compn(&comp, base_str, base_len)) {
- puts(" \tcouldn't parse");
- return 1;
- }
- if (semver_and(&comp, str, len)) {
- puts(" \tand failed");
- return 1;
- }
- slen = (unsigned) semver_comp_write(comp, buffer, 1024);
- printf(" \t=> \t`%.*s`", slen, buffer);
- if (memcmp(expected, buffer, (size_t) slen > base_len + len + 1 ? slen : base_len + len + 1) != 0) {
- printf(" != `%s`\n", expected);
- semver_comp_dtor(&comp);
- return 1;
- }
- printf(" == `%s`\n", expected);
- semver_comp_dtor(&comp);
- return 0;
-}
-
-int main(void) {
- puts("failure:");
- if (test_read("", STRNSIZE("* ")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("* ")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("* |")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("* || *")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("abc")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE(">")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("<=")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("~")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("^")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("=")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE(">a")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("<a")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("~a")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("^a")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("=a")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE(">1.a")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("<1.a")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("~1.a")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("^1.a")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("=1.a")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("1.2.3 ")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("1.2.3 -")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("1.2.3 - ")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("1.2.3 -a")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("1.2.3 - a")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("1.2.3 - 1.2.a")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("a.2.3")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("1.a.3")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("1.2.a")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("1.2.3-")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("1.2.3-alpha+")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("1.2.3+")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("1.2.3", STRNSIZE("1.2.3"))) {
- return EXIT_FAILURE;
- }
-
- puts("\nsome prerelease and build:");
- if (test_read(">=0.0.0 1.2.3-alpha", STRNSIZE("* 1.2.3-alpha"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=0.0.0 1.2.3-alpha.2", STRNSIZE("* 1.2.3-alpha.2"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=0.0.0 1.2.3+77", STRNSIZE("* 1.2.3+77"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=0.0.0 1.2.3+77.2", STRNSIZE("* 1.2.3+77.2"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=0.0.0 1.2.3-alpha.2+77", STRNSIZE("* 1.2.3-alpha.2+77"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=0.0.0 1.2.3-alpha.2+77.2", STRNSIZE("* 1.2.3-alpha.2+77.2"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=0.0.0 1.2.3-al-pha.2+77", STRNSIZE("* 1.2.3-al-pha.2+77"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=0.0.0 1.2.3-al-pha.2+77.2", STRNSIZE("* 1.2.3-al-pha.2+77.2"))) {
- return EXIT_FAILURE;
- }
-
- puts("\nx-range:");
- if (test_read(">=0.0.0", STRNSIZE("*"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=1.0.0 <2.0.0", STRNSIZE("1.x"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=1.2.0 <1.3.0", STRNSIZE("1.2.x"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=0.0.0", STRNSIZE(""))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=1.0.0 <2.0.0", STRNSIZE("1"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=1.2.0 <1.3.0", STRNSIZE("1.2"))) {
- return EXIT_FAILURE;
- }
-
- puts("\nhyphen:");
- if (test_read(">=1.2.3 <=2.3.4", STRNSIZE("1.2.3 - 2.3.4"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=1.2.0 <=2.3.4", STRNSIZE("1.2 - 2.3.4"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=1.2.3 <2.4.0", STRNSIZE("1.2.3 - 2.3"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=1.2.3 <3.0.0", STRNSIZE("1.2.3 - 2"))) {
- return EXIT_FAILURE;
- }
-
- puts("\ntidle:");
- if (test_read(">=1.2.3 <1.3.0", STRNSIZE("~1.2.3"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=1.2.0 <1.3.0", STRNSIZE("~1.2"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=1.0.0 <2.0.0", STRNSIZE("~1"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=0.2.3 <0.3.0", STRNSIZE("~0.2.3"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=0.2.0 <0.3.0", STRNSIZE("~0.2"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=0.0.0 <1.0.0", STRNSIZE("~0"))) {
- return EXIT_FAILURE;
- }
-
- puts("\ncaret:");
- if (test_read(">=1.2.3 <2.0.0", STRNSIZE("^1.2.3"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=0.2.3 <0.3.0", STRNSIZE("^0.2.3"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=0.0.3 <0.0.4", STRNSIZE("^0.0.3"))) {
- return EXIT_FAILURE;
- }
-
- puts("\nprimitive:");
- if (test_read(">=1.2.3 <2.0.0", STRNSIZE(">=1.2.3 <2.0"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=0.2.3 <0.3.0", STRNSIZE(">=0.2.3 <0.3"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=0.5.0 <0.0.4", STRNSIZE(">=0.5 <0.0.4"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">0.0.3", STRNSIZE(">0.0.3"))) {
- return EXIT_FAILURE;
- }
- if (test_read("0.0.3", STRNSIZE("=0.0.3"))) {
- return EXIT_FAILURE;
- }
- if (test_read("9.0.0", STRNSIZE("=9"))) {
- return EXIT_FAILURE;
- }
-
- puts("\nand:");
- if (test_and(">=0.0.0 >=0.0.3 <0.0.4", STRNSIZE("*"), STRNSIZE("^0.0.3"))) {
- return EXIT_FAILURE;
- }
- if (test_and(">=1.0.0 <2.0.0 >=0.0.3 <0.0.4", STRNSIZE("1.x"), STRNSIZE("^0.0.3"))) {
- return EXIT_FAILURE;
- }
- if (test_and(">=1.2.0 <1.3.0 >=0.0.3 <0.0.4", STRNSIZE("1.2.x"), STRNSIZE("^0.0.3"))) {
- return EXIT_FAILURE;
- }
- if (test_and(">=1.2.0 <1.3.0 >=1.2.0 <1.3.0 >=0.0.3 <0.0.4", STRNSIZE("1.2 1.2.x"), STRNSIZE("^0.0.3"))) {
- return EXIT_FAILURE;
- }
- if (test_and(">=1.0.0 <2.0.0 >=0.0.3 <0.0.4", STRNSIZE("1"), STRNSIZE("^0.0.3"))) {
- return EXIT_FAILURE;
- }
- if (test_and(">=1.2.0 <1.3.0 >=0.0.3 <0.0.4", STRNSIZE("1.2"), STRNSIZE("^0.0.3"))) {
- return EXIT_FAILURE;
- }
- if (test_and("", STRNSIZE("1.2"), STRNSIZE("")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_and("", STRNSIZE("1.2"), STRNSIZE("a")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_and("", STRNSIZE("1.2"), STRNSIZE("1.2.x abc")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget "
- "dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascet"
- "ur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, s"))
- == 0) {
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
diff --git a/core/src/sv/test/match.c b/core/src/sv/test/match.c
deleted file mode 100644
index d960bb7fc..000000000
--- a/core/src/sv/test/match.c
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * This is free and unencumbered software released into the public domain.
- *
- * Anyone is free to copy, modify, publish, use, compile, sell, or
- * distribute this software, either in source code form or as a compiled
- * binary, for any purpose, commercial or non-commercial, and by any
- * means.
- *
- * In jurisdictions that recognize copyright laws, the author or authors
- * of this software dedicate any and all copyright interest in the
- * software to the public domain. We make this dedication for the benefit
- * of the public at large and to the detriment of our heirs and
- * successors. We intend this dedication to be an overt act of
- * relinquishment in perpetuity of all present and future rights to this
- * software under copyright law.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * For more information, please refer to <http://unlicense.org>
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "semver.h"
-
-#define STRNSIZE(s) (s), sizeof(s)-1
-
-int test_matchn(bool expected, const char *semver_str, size_t semver_len, const char *comp_str, size_t comp_len) {
- bool result;
- semver_t semver = {0};
-
- printf("test: `%.*s` ^ `%.*s`", (int) semver_len, semver_str, (int) comp_len, comp_str);
- if (semvern(&semver, semver_str, semver_len)) {
- puts(" \tcouldn't parse semver");
- return 1;
- }
- result = semver_comp_matchn(&semver, comp_str, comp_len);
- printf(" \t=> %d\t", result);
- if (result != expected) {
- printf(" != `%d`\n", expected);
- semver_dtor(&semver);
- return 1;
- }
- printf(" == `%d`\n", expected);
- semver_dtor(&semver);
- return 0;
-}
-
-int test_rmatchn(bool expected, const char *semver_str, size_t semver_len, const char *range_str, size_t range_len) {
- bool result;
- semver_t semver = {0};
-
- printf("test: `%.*s` ^ `%.*s`", (int) semver_len, semver_str, (int) range_len, range_str);
- if (semvern(&semver, semver_str, semver_len)) {
- puts(" \tcouldn't parse semver");
- return 1;
- }
- result = semver_range_matchn(&semver, range_str, range_len);
- printf(" \t=> %d\t", result);
- if (result != expected) {
- printf(" != `%d`\n", expected);
- semver_dtor(&semver);
- return 1;
- }
- printf(" == `%d`\n", expected);
- semver_dtor(&semver);
- return 0;
-}
-
-int main(void) {
- if (test_matchn(true, STRNSIZE("v1.2.3"), STRNSIZE("1.2.3"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("v1.2.3"), STRNSIZE("1.2.x"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("v1.2.3"), STRNSIZE("1.x.x"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("v1.2.3"), STRNSIZE("1.x"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("v1.2.3"), STRNSIZE("1"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("v1.2.3"), STRNSIZE("*"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("v1.2.3"), STRNSIZE(">1"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(false, STRNSIZE("v1.2.3"), STRNSIZE(">2"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(false, STRNSIZE("v1.2.3"), STRNSIZE(">=2"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(false, STRNSIZE("v1.2.3"), STRNSIZE("<1"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(false, STRNSIZE("v1.2.3"), STRNSIZE("<=1"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("v1.2.3"), STRNSIZE(">=1.2.3"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(false, STRNSIZE("v1.2.3"), STRNSIZE(">1.2.3"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(false, STRNSIZE("v1.2.3"), STRNSIZE("<1.2.3"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("v1.2.3"), STRNSIZE("<=1.2.3"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(false, STRNSIZE("v1.2.3"), STRNSIZE("2.x"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-98"), STRNSIZE("<0.0.1-99"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-98"), STRNSIZE("<=0.0.1-99"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-98"), STRNSIZE("<=0.0.1-98"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-98"), STRNSIZE("=0.0.1-98"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-98"), STRNSIZE(">=0.0.1-98"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-98"), STRNSIZE(">=0.0.1-97"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-98"), STRNSIZE(">0.0.1-97"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-alpha"), STRNSIZE("0.0.1-alpha"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-98"), STRNSIZE("<0.0.1-99"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE("<0.0.1-alpha.99"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE("<=0.0.1-alpha.99"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE("<=0.0.1-alpha.98"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE("=0.0.1-alpha.98"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE(">=0.0.1-alpha.98"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE(">=0.0.1-alpha.97"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE(">0.0.1-alpha.97"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE("<0.0.1-alpha.99.1"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE("<=0.0.1-alpha.99.1"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE("<=0.0.1-alpha.98.1"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(false, STRNSIZE("0.0.1-alpha.98"), STRNSIZE("=0.0.1-alpha.98.1"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(false, STRNSIZE("0.0.1-alpha.98"), STRNSIZE(">=0.0.1-alpha.98.1"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE(">=0.0.1-alpha.97.1"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE(">0.0.1-alpha.97.1"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-alpha.98.1.3"), STRNSIZE("<0.0.1-alpha.99.1"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-alpha.98.1.3"), STRNSIZE("<=0.0.1-alpha.99.1"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(false, STRNSIZE("0.0.1-alpha.98.1.3"), STRNSIZE("<=0.0.1-alpha.98.1"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(false, STRNSIZE("0.0.1-alpha.98.1.3"), STRNSIZE("=0.0.1-alpha.98.1"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-alpha.98.1.3"), STRNSIZE(">=0.0.1-alpha.98.1"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-alpha.98.1.3"), STRNSIZE(">=0.0.1-alpha.97.1"))) {
- return EXIT_FAILURE;
- }
- if (test_matchn(true, STRNSIZE("0.0.1-alpha.98.1.3"), STRNSIZE(">0.0.1-alpha.97.1"))) {
- return EXIT_FAILURE;
- }
-
- if (test_rmatchn(true, STRNSIZE("v1.2.3"), STRNSIZE("9.x || 1.2.3"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("v1.2.3"), STRNSIZE("9.x || 1.2.x"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("v1.2.3"), STRNSIZE("9.x || 1.x.x"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("v1.2.3"), STRNSIZE("9.x || 1.x"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("v1.2.3"), STRNSIZE("9.x || 1"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("v1.2.3"), STRNSIZE("9.x || *"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("v1.2.3"), STRNSIZE("9.x || >1"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(false, STRNSIZE("v1.2.3"), STRNSIZE("9.x || >2"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(false, STRNSIZE("v1.2.3"), STRNSIZE("9.x || >=2"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(false, STRNSIZE("v1.2.3"), STRNSIZE("9.x || <1"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(false, STRNSIZE("v1.2.3"), STRNSIZE("9.x || <=1"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("v1.2.3"), STRNSIZE("9.x || >=1.2.3"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(false, STRNSIZE("v1.2.3"), STRNSIZE("9.x || >1.2.3"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(false, STRNSIZE("v1.2.3"), STRNSIZE("9.x || <1.2.3"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("v1.2.3"), STRNSIZE("9.x || <=1.2.3"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(false, STRNSIZE("v1.2.3"), STRNSIZE("9.x || 2.x"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-98"), STRNSIZE("9.x || <0.0.1-99"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-98"), STRNSIZE("9.x || <=0.0.1-99"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-98"), STRNSIZE("9.x || <=0.0.1-98"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-98"), STRNSIZE("9.x || =0.0.1-98"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-98"), STRNSIZE("9.x || >=0.0.1-98"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-98"), STRNSIZE("9.x || >=0.0.1-97"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-98"), STRNSIZE("9.x || >0.0.1-97"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-alpha"), STRNSIZE("9.x || 0.0.1-alpha"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-98"), STRNSIZE("9.x || <0.0.1-99"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE("9.x || <0.0.1-alpha.99"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE("9.x || <=0.0.1-alpha.99"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE("9.x || <=0.0.1-alpha.98"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE("9.x || =0.0.1-alpha.98"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE("9.x || >=0.0.1-alpha.98"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE("9.x || >=0.0.1-alpha.97"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE("9.x || >0.0.1-alpha.97"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE("9.x || <0.0.1-alpha.99.1"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE("9.x || <=0.0.1-alpha.99.1"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE("9.x || <=0.0.1-alpha.98.1"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(false, STRNSIZE("0.0.1-alpha.98"), STRNSIZE("9.x || =0.0.1-alpha.98.1"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(false, STRNSIZE("0.0.1-alpha.98"), STRNSIZE("9.x || >=0.0.1-alpha.98.1"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE("9.x || >=0.0.1-alpha.97.1"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-alpha.98"), STRNSIZE("9.x || >0.0.1-alpha.97.1"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-alpha.98.1.3"), STRNSIZE("9.x || <0.0.1-alpha.99.1"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-alpha.98.1.3"), STRNSIZE("9.x || <=0.0.1-alpha.99.1"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(false, STRNSIZE("0.0.1-alpha.98.1.3"), STRNSIZE("9.x || <=0.0.1-alpha.98.1"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(false, STRNSIZE("0.0.1-alpha.98.1.3"), STRNSIZE("9.x || =0.0.1-alpha.98.1"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-alpha.98.1.3"), STRNSIZE("9.x || >=0.0.1-alpha.98.1"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-alpha.98.1.3"), STRNSIZE("9.x || >=0.0.1-alpha.97.1"))) {
- return EXIT_FAILURE;
- }
- if (test_rmatchn(true, STRNSIZE("0.0.1-alpha.98.1.3"), STRNSIZE("9.x || >0.0.1-alpha.97.1"))) {
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
diff --git a/core/src/sv/test/range.c b/core/src/sv/test/range.c
deleted file mode 100644
index 17611ab25..000000000
--- a/core/src/sv/test/range.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * This is free and unencumbered software released into the public domain.
- *
- * Anyone is free to copy, modify, publish, use, compile, sell, or
- * distribute this software, either in source code form or as a compiled
- * binary, for any purpose, commercial or non-commercial, and by any
- * means.
- *
- * In jurisdictions that recognize copyright laws, the author or authors
- * of this software dedicate any and all copyright interest in the
- * software to the public domain. We make this dedication for the benefit
- * of the public at large and to the detriment of our heirs and
- * successors. We intend this dedication to be an overt act of
- * relinquishment in perpetuity of all present and future rights to this
- * software under copyright law.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * For more information, please refer to <http://unlicense.org>
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "semver.h"
-
-#define STRNSIZE(s) (s), sizeof(s)-1
-
-int test_read(const char *expected, const char *str, size_t len) {
- unsigned slen;
- char buffer[1024];
- semver_range_t range = {0};
-
- printf("test: `%.*s`", (int) len, str);
- if (semver_rangen(&range, str, len)) {
- puts(" \tcouldn't parse");
- return 1;
- }
- slen = (unsigned) semver_range_write(range, buffer, 1024);
- printf(" \t=> \t`%.*s`", slen, buffer);
- if (memcmp(expected, buffer, (size_t) slen > len ? slen : len) != 0) {
- printf(" != `%s`\n", expected);
- semver_range_dtor(&range);
- return 1;
- }
- printf(" == `%s`\n", expected);
- semver_range_dtor(&range);
- return 0;
-}
-
-int test_or(const char *expected, const char *base_str, size_t base_len, const char *str, size_t len) {
- unsigned slen;
- char buffer[1024];
- semver_range_t range = {0};
-
- printf("test and: `%.*s`", (int) base_len, base_str);
- if (semver_rangen(&range, base_str, base_len)) {
- puts(" \tcouldn't parse base");
- return 1;
- }
- if (semver_or(&range, str, len)) {
- puts(" \tand failed");
- return 1;
- }
- slen = (unsigned) semver_range_write(range, buffer, 1024);
- printf(" \t=> \t`%.*s`", slen, buffer);
- if (memcmp(expected, buffer, (size_t) slen > base_len + len + 1 ? slen : base_len + len + 1) != 0) {
- printf(" != `%s`\n", expected);
- semver_range_dtor(&range);
- return 1;
- }
- printf(" == `%s`\n", expected);
- semver_range_dtor(&range);
- return 0;
-}
-
-int main(void) {
- puts("failure:");
- if (test_read("", STRNSIZE("* |")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("* ||a")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("* || a")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("* || 1.a")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget "
- "dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascet"
- "ur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, s"))
- == 0) {
- return EXIT_FAILURE;
- }
-
- puts("\nx-range:");
- if (test_read(">=0.0.0 || 1.2.3", STRNSIZE("* || 1.2.3"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=1.0.0 <2.0.0 || >=2.0.0 <3.0.0", STRNSIZE("1.x || 2.x"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=1.2.0 <1.3.0 || 3.0.0", STRNSIZE("1.2.x || 3.0.0"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=0.0.0", STRNSIZE(""))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=1.0.0 <2.0.0 || >=2.0.0 <3.0.0 || >=3.0.0 <4.0.0", STRNSIZE("1 || 2 || 3"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=1.2.0 <1.3.0 || >=5.0.0", STRNSIZE("1.2 || >=5"))) {
- return EXIT_FAILURE;
- }
-
- puts("\nhyphen:");
- if (test_read(">=1.2.3 <=2.3.4 || >=5.0.0", STRNSIZE("1.2.3 - 2.3.4 || >=5"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=1.2.0 <=2.3.4 || >=5.0.0", STRNSIZE("1.2 - 2.3.4 || >=5"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=1.2.3 <2.4.0 || >=5.0.0", STRNSIZE("1.2.3 - 2.3 || >=5"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=1.2.3 <3.0.0 || >=5.0.0", STRNSIZE("1.2.3 - 2 || >=5"))) {
- return EXIT_FAILURE;
- }
-
- puts("\ntidle:");
- if (test_read(">=1.2.3 <1.3.0 || >=5.0.0", STRNSIZE("~1.2.3 || >=5"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=1.2.0 <1.3.0 || >=5.0.0", STRNSIZE("~1.2 || >=5"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=1.0.0 <2.0.0 || >=5.0.0", STRNSIZE("~1 || >=5"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=0.2.3 <0.3.0 || >=5.0.0", STRNSIZE("~0.2.3 || >=5"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=0.2.0 <0.3.0 || >=5.0.0", STRNSIZE("~0.2 || >=5"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=0.0.0 <1.0.0 || >=5.0.0", STRNSIZE("~0 || >=5"))) {
- return EXIT_FAILURE;
- }
-
- puts("\ncaret:");
- if (test_read(">=1.2.3 <2.0.0 || >=5.0.0", STRNSIZE("^1.2.3 || >=5"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=0.2.3 <0.3.0 || >=5.0.0", STRNSIZE("^0.2.3 || >=5"))) {
- return EXIT_FAILURE;
- }
- if (test_read(">=0.0.3 <0.0.4 || >=5.0.0", STRNSIZE("^0.0.3 || >=5"))) {
- return EXIT_FAILURE;
- }
-
- puts("\nand:");
- if (test_or(">=0.0.0 || >=0.0.3 <0.0.4", STRNSIZE("*"), STRNSIZE("^0.0.3"))) {
- return EXIT_FAILURE;
- }
- if (test_or(">=1.0.0 <2.0.0 || >=0.0.3 <0.0.4", STRNSIZE("1.x"), STRNSIZE("^0.0.3"))) {
- return EXIT_FAILURE;
- }
- if (test_or(">=1.2.0 <1.3.0 || >=0.0.3 <0.0.4", STRNSIZE("1.2.x"), STRNSIZE("^0.0.3"))) {
- return EXIT_FAILURE;
- }
- if (test_or(">=1.2.0 <1.3.0 || >=1.2.0 <1.3.0 || >=0.0.3 <0.0.4", STRNSIZE("1.2 || 1.2.x"), STRNSIZE("^0.0.3"))) {
- return EXIT_FAILURE;
- }
- if (test_or(">=1.0.0 <2.0.0 || >=0.0.3 <0.0.4", STRNSIZE("1"), STRNSIZE("^0.0.3"))) {
- return EXIT_FAILURE;
- }
- if (test_or(">=1.2.0 <1.3.0 || >=0.0.3 <0.0.4", STRNSIZE("1.2"), STRNSIZE("^0.0.3"))) {
- return EXIT_FAILURE;
- }
- if (test_or("", STRNSIZE("1.2"), STRNSIZE("")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_or("", STRNSIZE("1.2"), STRNSIZE("a")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_or("", STRNSIZE("1.2"), STRNSIZE("1.2.x || abc")) == 0) {
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
diff --git a/core/src/sv/test/semver.c b/core/src/sv/test/semver.c
deleted file mode 100644
index 762f4ce40..000000000
--- a/core/src/sv/test/semver.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * This is free and unencumbered software released into the public domain.
- *
- * Anyone is free to copy, modify, publish, use, compile, sell, or
- * distribute this software, either in source code form or as a compiled
- * binary, for any purpose, commercial or non-commercial, and by any
- * means.
- *
- * In jurisdictions that recognize copyright laws, the author or authors
- * of this software dedicate any and all copyright interest in the
- * software to the public domain. We make this dedication for the benefit
- * of the public at large and to the detriment of our heirs and
- * successors. We intend this dedication to be an overt act of
- * relinquishment in perpetuity of all present and future rights to this
- * software under copyright law.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * For more information, please refer to <http://unlicense.org>
- */
-
-#include <semver.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#define STRNSIZE(s) (s), sizeof(s)-1
-
-int test_semver(const char *expected, const char *str, size_t len) {
- size_t offset = 0;
- unsigned slen;
- char buffer[1024];
- semver_t semver = {0};
-
- printf("test: `%.*s`", (int) len, str);
- if (semver_read(&semver, str, len, &offset)) {
- puts(" \tcouldn't parse");
- return 1;
- }
- slen = (unsigned) semver_write(semver, buffer, 1024);
- printf(" \t=> \t`%.*s`", slen, buffer);
- if (memcmp(expected, buffer, (size_t) slen > len ? slen : len) != 0) {
- printf(" != `%s`\n", expected);
- semver_dtor(&semver);
- return 1;
- }
- printf(" == `%s`\n", expected);
- semver_dtor(&semver);
- return 0;
-}
-
-int main(void) {
- if (test_semver("1.2.3", STRNSIZE("1.2.3"))) {
- return EXIT_FAILURE;
- }
- if (test_semver("1.2.3-alpha", STRNSIZE("v1.2.3-alpha"))) {
- return EXIT_FAILURE;
- }
- if (test_semver("1.2.3-alpha.2", STRNSIZE("1.2.3-alpha.2"))) {
- return EXIT_FAILURE;
- }
- if (test_semver("1.2.3+77", STRNSIZE("v1.2.3+77"))) {
- return EXIT_FAILURE;
- }
- if (test_semver("1.2.3+77.2", STRNSIZE("1.2.3+77.2"))) {
- return EXIT_FAILURE;
- }
- if (test_semver("1.2.3-alpha.2+77", STRNSIZE("v1.2.3-alpha.2+77"))) {
- return EXIT_FAILURE;
- }
- if (test_semver("1.2.3-alpha.2+77.2", STRNSIZE("1.2.3-alpha.2+77.2"))) {
- return EXIT_FAILURE;
- }
- if (test_semver("1.2.3-al-pha.2+77", STRNSIZE("v1.2.3-al-pha.2+77"))) {
- return EXIT_FAILURE;
- }
- if (test_semver("1.2.3-al-pha.2+77.2", STRNSIZE("1.2.3-al-pha.2+77.2"))) {
- return EXIT_FAILURE;
- }
- if (test_semver("", STRNSIZE("")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_semver("", STRNSIZE("vv1.2.3")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_semver("", STRNSIZE("v1.2")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_semver("", STRNSIZE("v1.2.x")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_semver("", STRNSIZE("v1.2.3-")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_semver("", STRNSIZE("v1.2.3+")) == 0) {
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
diff --git a/core/src/sv/test/semvers.c b/core/src/sv/test/semvers.c
deleted file mode 100644
index fec6072bd..000000000
--- a/core/src/sv/test/semvers.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * This is free and unencumbered software released into the public domain.
- *
- * Anyone is free to copy, modify, publish, use, compile, sell, or
- * distribute this software, either in source code form or as a compiled
- * binary, for any purpose, commercial or non-commercial, and by any
- * means.
- *
- * In jurisdictions that recognize copyright laws, the author or authors
- * of this software dedicate any and all copyright interest in the
- * software to the public domain. We make this dedication for the benefit
- * of the public at large and to the detriment of our heirs and
- * successors. We intend this dedication to be an overt act of
- * relinquishment in perpetuity of all present and future rights to this
- * software under copyright law.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * For more information, please refer to <http://unlicense.org>
- */
-
-#include <stdlib.h>
-#include <assert.h>
-
-#include "semver.h"
-
-#define STRNSIZE(s) (s), sizeof(s)-1
-
-int main(void) {
- semver_t v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10;
- semvers_t semvers = {0};
-
- semver_tryn(&v0, STRNSIZE("2.0.0"));
- semver_tryn(&v1, STRNSIZE("2.0.1"));
- semver_tryn(&v2, STRNSIZE("2.0.2"));
- semver_tryn(&v3, STRNSIZE("v2.0.0"));
- semver_tryn(&v4, STRNSIZE("v2.0.1"));
- semver_tryn(&v5, STRNSIZE("v2.0.2"));
- semver_tryn(&v6, STRNSIZE("v2.0.3"));
- semver_tryn(&v7, STRNSIZE("v2.1.0-beta1"));
- semver_tryn(&v8, STRNSIZE("v2.1.0-beta2"));
- semver_tryn(&v9, STRNSIZE("v2.0"));
- semver_tryn(&v10, STRNSIZE("v2.1"));
-
- if (semver_rmatch(v0, ">2.0.1")) semvers_push(semvers, v0);
- if (semver_rmatch(v1, ">2.0.1")) semvers_unshift(semvers, v1);
- if (semver_rmatch(v2, ">2.0.1")) semvers_push(semvers, v2);
- if (semver_rmatch(v3, ">2.0.1")) semvers_unshift(semvers, v3);
- if (semver_rmatch(v4, ">2.0.1")) semvers_push(semvers, v4);
- if (semver_rmatch(v5, ">2.0.1")) semvers_unshift(semvers, v5);
- if (semver_rmatch(v6, ">2.0.1")) semvers_push(semvers, v6);
- if (semver_rmatch(v7, ">2.0.1")) semvers_unshift(semvers, v7);
- if (semver_rmatch(v8, ">2.0.1")) semvers_push(semvers, v8);
- if (semver_rmatch(v9, ">2.0.1")) semvers_unshift(semvers, v9);
- if (semver_rmatch(v10, ">2.0.1")) semvers_push(semvers, v10);
- if (semver_rmatch(v0, ">2.0.1")) semvers_push(semvers, v0);
- if (semver_rmatch(v1, ">2.0.1")) semvers_unshift(semvers, v1);
- if (semver_rmatch(v2, ">2.0.1")) semvers_push(semvers, v2);
- if (semver_rmatch(v3, ">2.0.1")) semvers_unshift(semvers, v3);
- if (semver_rmatch(v4, ">2.0.1")) semvers_push(semvers, v4);
- if (semver_rmatch(v5, ">2.0.1")) semvers_unshift(semvers, v5);
- if (semver_rmatch(v6, ">2.0.1")) semvers_push(semvers, v6);
- if (semver_rmatch(v7, ">2.0.1")) semvers_unshift(semvers, v7);
- if (semver_rmatch(v8, ">2.0.1")) semvers_push(semvers, v8);
- if (semver_rmatch(v9, ">2.0.1")) semvers_unshift(semvers, v9);
- if (semver_rmatch(v10, ">2.0.1")) semvers_push(semvers, v10);
- if (semver_rmatch(v0, ">2.0.1")) semvers_push(semvers, v0);
- if (semver_rmatch(v1, ">2.0.1")) semvers_unshift(semvers, v1);
- if (semver_rmatch(v2, ">2.0.1")) semvers_push(semvers, v2);
- if (semver_rmatch(v3, ">2.0.1")) semvers_unshift(semvers, v3);
- if (semver_rmatch(v4, ">2.0.1")) semvers_push(semvers, v4);
- if (semver_rmatch(v5, ">2.0.1")) semvers_unshift(semvers, v5);
- if (semver_rmatch(v6, ">2.0.1")) semvers_push(semvers, v6);
- if (semver_rmatch(v7, ">2.0.1")) semvers_unshift(semvers, v7);
- if (semver_rmatch(v8, ">2.0.1")) semvers_push(semvers, v8);
- if (semver_rmatch(v9, ">2.0.1")) semvers_unshift(semvers, v9);
- if (semver_rmatch(v10, ">2.0.1")) semvers_push(semvers, v10);
-
- if (semvers.length != 18) {
- return EXIT_FAILURE;
- }
- if (semvers.capacity != 32) {
- return EXIT_FAILURE;
- }
-
- semvers_sort(semvers);
-
- for (unsigned i = 0; i < semvers.length; ++i) {
- semver_fwrite(semvers.data + i, stdout);
- putc('\n', stdout);
- }
-
- v0 = semvers_pop(semvers);
- v1 = semvers_shift(semvers);
-
- assert(memcmp("v2.1", v0.raw, v0.len) == 0);
- assert(memcmp("v2.0.2", v1.raw, v1.len) == 0 || memcmp("2.0.2", v1.raw, v1.len) == 0);
-
- semvers_rsort(semvers);
- putc('\n', stdout);
- for (unsigned i = 0; i < semvers.length; ++i) {
- semver_fwrite(semvers.data + i, stdout);
- putc('\n', stdout);
- }
-
- semvers_dtor(semvers);
-
- return EXIT_SUCCESS;
-}
diff --git a/core/src/sv/test/usage.c b/core/src/sv/test/usage.c
deleted file mode 100644
index 818608137..000000000
--- a/core/src/sv/test/usage.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * This is free and unencumbered software released into the public domain.
- *
- * Anyone is free to copy, modify, publish, use, compile, sell, or
- * distribute this software, either in source code form or as a compiled
- * binary, for any purpose, commercial or non-commercial, and by any
- * means.
- *
- * In jurisdictions that recognize copyright laws, the author or authors
- * of this software dedicate any and all copyright interest in the
- * software to the public domain. We make this dedication for the benefit
- * of the public at large and to the detriment of our heirs and
- * successors. We intend this dedication to be an overt act of
- * relinquishment in perpetuity of all present and future rights to this
- * software under copyright law.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * For more information, please refer to <http://unlicense.org>
- */
-
-#include <stdlib.h>
-#include <assert.h>
-
-#include "semver.h"
-
-int main(void) {
- semver_t semver = {0};
-
- semver(&semver, "v1.2.3-alpha.1");
-
- assert(1 == semver.major);
- assert(2 == semver.minor);
- assert(3 == semver.patch);
- assert(0 == memcmp("alpha", semver.prerelease.raw, sizeof("alpha")-1));
- assert(0 == memcmp("1", semver.prerelease.next->raw, sizeof("1")-1));
- assert(true == semver_rmatch(semver, "1.2.1 || >=1.2.3-alpha <1.2.5"));
-
- semver_dtor(&semver);
-}
diff --git a/core/src/sv/test/utils.c b/core/src/sv/test/utils.c
deleted file mode 100644
index 89ae4cd1b..000000000
--- a/core/src/sv/test/utils.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * This is free and unencumbered software released into the public domain.
- *
- * Anyone is free to copy, modify, publish, use, compile, sell, or
- * distribute this software, either in source code form or as a compiled
- * binary, for any purpose, commercial or non-commercial, and by any
- * means.
- *
- * In jurisdictions that recognize copyright laws, the author or authors
- * of this software dedicate any and all copyright interest in the
- * software to the public domain. We make this dedication for the benefit
- * of the public at large and to the detriment of our heirs and
- * successors. We intend this dedication to be an overt act of
- * relinquishment in perpetuity of all present and future rights to this
- * software under copyright law.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * For more information, please refer to <http://unlicense.org>
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#include "semver.h"
-
-int test_version_fwrite(void) {
- static const char input_str[] = "1.2.3-alpha.1+x86-64";
- semver_t version;
- int rv;
-
- rv = semver(&version, input_str);
- if (0 == rv) {
- printf("test_version_fwrite: ");
- semver_fwrite(&version, stdout);
- if (0 == errno) {
- printf("\n");
- rv = 0;
- }
- }
- semver_dtor(&version);
- return rv;
-}
-
-int test_comparator_fwrite(void) {
- static const char input_str[] = "<=1.2.3";
- semver_comp_t comp;
- int rv;
-
- rv = semver_comp(&comp, input_str);
- if (0 == rv) {
- printf("test_comparator_fwrite: ");
- semver_comp_fwrite(&comp, stdout);
- if (0 == errno) {
- printf("\n");
- rv = 0;
- }
- }
- semver_comp_dtor(&comp);
- return rv;
-}
-
-int test_range_fwrite(void) {
- static const char input_str[] = ">=1.2.3 <4.0.0";
- semver_range_t range;
- int rv;
-
- rv = semver_range(&range, input_str);
- if (0 == rv) {
- printf("test_range_fwrite: ");
- semver_range_fwrite(&range, stdout);
- if (0 == errno) {
- printf("\n");
- rv = 0;
- }
- }
- semver_range_dtor(&range);
- return rv;
-}
-
-int main(void) {
- if (test_version_fwrite()) {
- return EXIT_FAILURE;
- }
-
- if (test_comparator_fwrite()) {
- return EXIT_FAILURE;
- }
-
- if (test_range_fwrite()) {
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
diff --git a/core/src/sv/test/version.c b/core/src/sv/test/version.c
deleted file mode 100644
index a10b6e645..000000000
--- a/core/src/sv/test/version.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * This is free and unencumbered software released into the public domain.
- *
- * Anyone is free to copy, modify, publish, use, compile, sell, or
- * distribute this software, either in source code form or as a compiled
- * binary, for any purpose, commercial or non-commercial, and by any
- * means.
- *
- * In jurisdictions that recognize copyright laws, the author or authors
- * of this software dedicate any and all copyright interest in the
- * software to the public domain. We make this dedication for the benefit
- * of the public at large and to the detriment of our heirs and
- * successors. We intend this dedication to be an overt act of
- * relinquishment in perpetuity of all present and future rights to this
- * software under copyright law.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * For more information, please refer to <http://unlicense.org>
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "semver.h"
-
-#define STRNSIZE(s) (s), sizeof(s)-1
-
-int test_read(const char *expected, const char *str, size_t len) {
- unsigned slen;
- char buffer[1024];
- semver_t semver = {0};
-
- printf("test: `%.*s`", (int) len, str);
- if (semvern(&semver, str, len)) {
- puts(" \tcouldn't parse");
- return 1;
- }
- slen = (unsigned) semver_write(semver, buffer, 1024);
- printf(" \t=> \t`%.*s`", slen, buffer);
- if (memcmp(expected, buffer, (size_t) slen > len ? slen : len) != 0) {
- printf(" != `%s`\n", expected);
- semver_dtor(&semver);
- return 1;
- }
- printf(" == `%s`\n", expected);
- semver_dtor(&semver);
- return 0;
-}
-
-int test_try_read(const char *expected, const char *str, size_t len) {
- unsigned slen;
- char buffer[1024];
- semver_t semver = {0};
-
- printf("test: `%.*s`", (int) len, str);
- if (semver_tryn(&semver, str, len)) {
- puts(" \tcouldn't parse");
- return 1;
- }
- slen = (unsigned) semver_write(semver, buffer, 1024);
- printf(" \t=> \t`%.*s`", slen, buffer);
- if (memcmp(expected, buffer, (size_t) slen > len ? slen : len) != 0) {
- printf(" != `%s`\n", expected);
- semver_dtor(&semver);
- return 1;
- }
- printf(" == `%s`\n", expected);
- semver_dtor(&semver);
- return 0;
-}
-
-int main(void) {
- puts("normal:");
- if (test_read("0.2.3", STRNSIZE("0.2.3"))) {
- return EXIT_FAILURE;
- }
- if (test_read("1.2.3", STRNSIZE("1.2.3"))) {
- return EXIT_FAILURE;
- }
- if (test_read("1.2.3-alpha", STRNSIZE("v1.2.3-alpha"))) {
- return EXIT_FAILURE;
- }
- if (test_read("1.2.3-alpha.2", STRNSIZE("1.2.3-alpha.2"))) {
- return EXIT_FAILURE;
- }
- if (test_read("1.2.3+77", STRNSIZE("v1.2.3+77"))) {
- return EXIT_FAILURE;
- }
- if (test_read("1.2.3+0", STRNSIZE("v1.2.3+0"))) {
- return EXIT_FAILURE;
- }
- if (test_read("1.2.3+77.2", STRNSIZE("1.2.3+77.2"))) {
- return EXIT_FAILURE;
- }
- if (test_read("1.2.3-alpha.2+77", STRNSIZE("v1.2.3-alpha.2+77"))) {
- return EXIT_FAILURE;
- }
- if (test_read("1.2.3-alpha.2+77.2", STRNSIZE("1.2.3-alpha.2+77.2"))) {
- return EXIT_FAILURE;
- }
- if (test_read("1.2.3-al-pha.2+77", STRNSIZE("v1.2.3-al-pha.2+77"))) {
- return EXIT_FAILURE;
- }
- if (test_read("1.2.3-al-pha.2+77.2", STRNSIZE("1.2.3-al-pha.2+77.2"))) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("vv1.2.3")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("v1.2")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("v1.2.x")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("v1.2.3-")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("v1.2.3+")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("v1.2.3+01")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("v0.01.3")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_read("", STRNSIZE("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget "
- "dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascet"
- "ur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, s"))
- == 0) {
- return EXIT_FAILURE;
- }
-
- puts("try:");
- if (test_try_read("0.2.3", STRNSIZE("0.2.3"))) {
- return EXIT_FAILURE;
- }
- if (test_try_read("1.2.3", STRNSIZE("1.2.3"))) {
- return EXIT_FAILURE;
- }
- if (test_try_read("1.2.3-alpha", STRNSIZE("v1.2.3-alpha"))) {
- return EXIT_FAILURE;
- }
- if (test_try_read("1.2.3-alpha.2", STRNSIZE("1.2.3-alpha.2"))) {
- return EXIT_FAILURE;
- }
- if (test_try_read("1.2.3+77", STRNSIZE("v1.2.3+77"))) {
- return EXIT_FAILURE;
- }
- if (test_try_read("1.2.3+0", STRNSIZE("v1.2.3+0"))) {
- return EXIT_FAILURE;
- }
- if (test_try_read("1.2.3+77.2", STRNSIZE("1.2.3+77.2"))) {
- return EXIT_FAILURE;
- }
- if (test_try_read("1.2.3-alpha.2+77", STRNSIZE("v1.2.3-alpha.2+77"))) {
- return EXIT_FAILURE;
- }
- if (test_try_read("1.2.3-alpha.2+77.2", STRNSIZE("1.2.3-alpha.2+77.2"))) {
- return EXIT_FAILURE;
- }
- if (test_try_read("1.2.3-al-pha.2+77", STRNSIZE("v1.2.3-al-pha.2+77"))) {
- return EXIT_FAILURE;
- }
- if (test_try_read("1.2.3-al-pha.2+77.2", STRNSIZE("1.2.3-al-pha.2+77.2"))) {
- return EXIT_FAILURE;
- }
- if (test_try_read("", STRNSIZE("")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_try_read("", STRNSIZE("vv1.2.3")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_try_read("", STRNSIZE("v1.2")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_try_read("", STRNSIZE("v1.2.x")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_try_read("", STRNSIZE("v1.2.3-")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_try_read("", STRNSIZE("v1.2.3+")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_try_read("", STRNSIZE("v1.2.3+01")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_try_read("", STRNSIZE("v0.01.3")) == 0) {
- return EXIT_FAILURE;
- }
- if (test_try_read("", STRNSIZE("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget "
- "dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascet"
- "ur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, s"))
- == 0) {
- return EXIT_FAILURE;
- }
- if (test_try_read("0.2.0", STRNSIZE("0.2"))) {
- return EXIT_FAILURE;
- }
- if (test_try_read("1.0.0", STRNSIZE("v1"))) {
- return EXIT_FAILURE;
- }
- if (test_try_read("1.2.0-alpha", STRNSIZE("v1.2alpha"))) {
- return EXIT_FAILURE;
- }
- if (test_try_read("1.2.3-alpha.2", STRNSIZE("1.2.3alpha.2"))) {
- return EXIT_FAILURE;
- }
- if (test_try_read("1.0.0+77", STRNSIZE("v1+77"))) {
- return EXIT_FAILURE;
- }
- if (test_try_read("1.2.0+0", STRNSIZE("v1.2+0"))) {
- return EXIT_FAILURE;
- }
- if (test_try_read("1.0.0+77.2", STRNSIZE("v1+77.2"))) {
- return EXIT_FAILURE;
- }
- if (test_try_read("1.2.3-alpha.2+77", STRNSIZE("v1.2.3alpha.2+77"))) {
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
diff --git a/core/src/sv/test/xmake.lua b/core/src/sv/test/xmake.lua
deleted file mode 100644
index 4169560e8..000000000
--- a/core/src/sv/test/xmake.lua
+++ /dev/null
@@ -1,45 +0,0 @@
-set_default(false)
-set_languages("c99")
-set_kind("binary")
-add_deps("sv")
-add_links("sv")
-add_includedirs("../include")
-add_linkdirs("$(buildir)")
-
-target("version_test")
- add_files("version.c")
-
-target("comp_test")
- add_files("comp.c")
-
-target("range_test")
- add_files("range.c")
-
-target("match_test")
- add_files("match.c")
-
-target("semvers_test")
- add_files("semvers.c")
-
-target("utils_test")
- add_files("utils.c")
-
-target("usage_test")
- add_files("usage.c")
-
-task("check")
- on_run(function ()
- import("core.project.task")
- task.run("run", {target = "version_test"})
- task.run("run", {target = "comp_test"})
- task.run("run", {target = "range_test"})
- task.run("run", {target = "match_test"})
- task.run("run", {target = "semvers_test"})
- task.run("run", {target = "utils_test"})
- task.run("run", {target = "usage_test"})
- end)
- set_menu {
- usage = "xmake check"
- , description = "Run tests !"
- , options = {}
- }
diff --git a/core/src/tbox/src/tbox/asio/asio.h b/core/src/tbox/src/tbox/asio/asio.h
deleted file mode 100644
index bb4f1ea7d..000000000
--- a/core/src/tbox/src/tbox/asio/asio.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file asio.h
- *
- */
-#ifndef TB_ASIO_H
-#define TB_ASIO_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-#ifdef TB_CONFIG_API_HAVE_DEPRECATED
-# include "deprecated/deprecated.h"
-#endif
-
-#endif
diff --git a/core/src/tbox/src/tbox/asio/deprecated/aice.h b/core/src/tbox/src/tbox/asio/deprecated/aice.h
deleted file mode 100644
index 90a4ea661..000000000
--- a/core/src/tbox/src/tbox/asio/deprecated/aice.h
+++ /dev/null
@@ -1,484 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file aice.h
- * @ingroup asio
- */
-#ifndef TB_ASIO_AICE_H
-#define TB_ASIO_AICE_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "aico.h"
-#include "../../network/ipaddr.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the aice code enum
-typedef enum __tb_aice_code_e
-{
- TB_AICE_CODE_NONE = 0
-
-, TB_AICE_CODE_ACPT = 1 //!< for sock, accept it
-, TB_AICE_CODE_CONN = 2 //!< for sock, connect to the host address
-, TB_AICE_CODE_RECV = 3 //!< for sock, recv data for tcp
-, TB_AICE_CODE_SEND = 4 //!< for sock, send data for tcp
-, TB_AICE_CODE_URECV = 5 //!< for sock, recv data for udp
-, TB_AICE_CODE_USEND = 6 //!< for sock, send data for udp
-, TB_AICE_CODE_RECVV = 7 //!< for sock, recv iovec data for tcp
-, TB_AICE_CODE_SENDV = 8 //!< for sock, send iovec data for tcp
-, TB_AICE_CODE_URECVV = 9 //!< for sock, recv iovec data for udp
-, TB_AICE_CODE_USENDV = 10 //!< for sock, send iovec data for udp
-, TB_AICE_CODE_SENDF = 11 //!< for sock, maybe return TB_STATE_NOT_SUPPORTED
-
-, TB_AICE_CODE_READ = 12 //!< for file, read data
-, TB_AICE_CODE_WRIT = 13 //!< for file, writ data
-, TB_AICE_CODE_READV = 14 //!< for file, read iovec data
-, TB_AICE_CODE_WRITV = 15 //!< for file, writ iovec data
-, TB_AICE_CODE_FSYNC = 16 //!< for file, flush data to file
-
-, TB_AICE_CODE_RUNTASK = 17 //!< for task or sock or file, run task with the given delay
-, TB_AICE_CODE_CLOS = 18 //!< for task or sock or file
-
-, TB_AICE_CODE_MAXN = 19
-
-}tb_aice_code_e;
-
-/// the acpt aice type
-typedef struct __tb_aice_acpt_t
-{
- /// the client aico
- tb_aico_ref_t aico;
-
- /// the client addr
- tb_ipaddr_t addr;
-
- /// the private data for using the left space of the union
- tb_cpointer_t priv[1];
-
-}tb_aice_acpt_t;
-
-/// the conn aice type
-typedef struct __tb_aice_conn_t
-{
- /// the addr
- tb_ipaddr_t addr;
-
-}tb_aice_conn_t;
-
-#ifdef TB_CONFIG_OS_WINDOWS
-/// the recv aice type, base: tb_iovec_t
-typedef struct __tb_aice_recv_t
-{
- /// the data size for (tb_iovec_t*)->size
- tb_iovec_size_t size;
-
- /// the recv data for (tb_iovec_t*)->data
- tb_byte_t* data;
-
- /// the data real
- tb_size_t real;
-
-}tb_aice_recv_t;
-
-/// the send aice type, base: tb_iovec_t
-typedef struct __tb_aice_send_t
-{
- /// the data size for (tb_iovec_t*)->size
- tb_iovec_size_t size;
-
- /// the send data for (tb_iovec_t*)->data
- tb_byte_t const* data;
-
- /// the data real
- tb_size_t real;
-
-}tb_aice_send_t;
-
-/// the urecv aice type, base: tb_iovec_t
-typedef struct __tb_aice_urecv_t
-{
- /// the data size for (tb_iovec_t*)->size
- tb_iovec_size_t size;
-
- /// the recv data for (tb_iovec_t*)->data
- tb_byte_t* data;
-
- /// the data real
- tb_size_t real;
-
- /// the addr
- tb_ipaddr_t addr;
-
-}tb_aice_urecv_t;
-
-/// the usend aice type, base: tb_iovec_t
-typedef struct __tb_aice_usend_t
-{
- /// the data size for (tb_iovec_t*)->size
- tb_iovec_size_t size;
-
- /// the send data for (tb_iovec_t*)->data
- tb_byte_t const* data;
-
- /// the data real
- tb_size_t real;
-
- /// the peer addr
- tb_ipaddr_t addr;
-
-}tb_aice_usend_t;
-
-/// the read aice type, base: tb_iovec_t
-typedef struct __tb_aice_read_t
-{
- /// the data size for (tb_iovec_t*)->size
- tb_iovec_size_t size;
-
- /// the read data for (tb_iovec_t*)->data
- tb_byte_t* data;
-
- /// the data real
- tb_size_t real;
-
- /// the file seek
- tb_hize_t seek;
-
-}tb_aice_read_t;
-
-/// the writ aice type, base: tb_iovec_t
-typedef struct __tb_aice_writ_t
-{
- /// the data size for (tb_iovec_t*)->size
- tb_iovec_size_t size;
-
- /// the writ data for (tb_iovec_t*)->data
- tb_byte_t const* data;
-
- /// the data real
- tb_size_t real;
-
- /// the file seek
- tb_hize_t seek;
-
-}tb_aice_writ_t;
-#else
-/// the recv aice type, base: tb_iovec_t
-typedef struct __tb_aice_recv_t
-{
- /// the recv data for (tb_iovec_t*)->data
- tb_byte_t* data;
-
- /// the data size for (tb_iovec_t*)->size
- tb_iovec_size_t size;
-
- /// the data real
- tb_size_t real;
-
-}tb_aice_recv_t;
-
-/// the send aice type, base: tb_iovec_t
-typedef struct __tb_aice_send_t
-{
- /// the send data for (tb_iovec_t*)->data
- tb_byte_t const* data;
-
- /// the data size for (tb_iovec_t*)->size
- tb_iovec_size_t size;
-
- /// the data real
- tb_size_t real;
-
-}tb_aice_send_t;
-
-/// the urecv aice type, base: tb_iovec_t
-typedef struct __tb_aice_urecv_t
-{
- /// the recv data for (tb_iovec_t*)->data
- tb_byte_t* data;
-
- /// the data size for (tb_iovec_t*)->size
- tb_iovec_size_t size;
-
- /// the data real
- tb_size_t real;
-
- /// the addr
- tb_ipaddr_t addr;
-
-}tb_aice_urecv_t;
-
-/// the usend aice type, base: tb_iovec_t
-typedef struct __tb_aice_usend_t
-{
- /// the send data for (tb_iovec_t*)->data
- tb_byte_t const* data;
-
- /// the data size for (tb_iovec_t*)->size
- tb_iovec_size_t size;
-
- /// the data real
- tb_size_t real;
-
- /// the addr
- tb_ipaddr_t addr;
-
-}tb_aice_usend_t;
-
-/// the read aice type, base: tb_iovec_t
-typedef struct __tb_aice_read_t
-{
- /// the read data for (tb_iovec_t*)->data
- tb_byte_t* data;
-
- /// the data size for (tb_iovec_t*)->size
- tb_iovec_size_t size;
-
- /// the data real
- tb_size_t real;
-
- /// the file seek
- tb_hize_t seek;
-
-}tb_aice_read_t;
-
-/// the writ aice type, base: tb_iovec_t
-typedef struct __tb_aice_writ_t
-{
- /// the writ data for (tb_iovec_t*)->data
- tb_byte_t const* data;
-
- /// the data size for (tb_iovec_t*)->size
- tb_iovec_size_t size;
-
- /// the data real
- tb_size_t real;
-
- /// the file seek
- tb_hize_t seek;
-
-}tb_aice_writ_t;
-#endif
-
-/// the recvv aice type
-typedef struct __tb_aice_recvv_t
-{
- /// the recv list
- tb_iovec_t const* list;
-
- /// the list size
- tb_size_t size;
-
- /// the data real
- tb_size_t real;
-
-}tb_aice_recvv_t;
-
-/// the sendv aice type
-typedef struct __tb_aice_sendv_t
-{
- /// the send list
- tb_iovec_t const* list;
-
- /// the list size
- tb_size_t size;
-
- /// the data real
- tb_size_t real;
-
-}tb_aice_sendv_t;
-
-/// the urecvv aice type
-typedef struct __tb_aice_urecvv_t
-{
- /// the recv list
- tb_iovec_t const* list;
-
- /// the list size
- tb_size_t size;
-
- /// the data real
- tb_size_t real;
-
- /// the peer addr
- tb_ipaddr_t addr;
-
-}tb_aice_urecvv_t;
-
-/// the usendv aice type
-typedef struct __tb_aice_usendv_t
-{
- /// the send list
- tb_iovec_t const* list;
-
- /// the list size
- tb_size_t size;
-
- /// the data real
- tb_size_t real;
-
- /// the addr
- tb_ipaddr_t addr;
-
-}tb_aice_usendv_t;
-
-/// the sendf aice type
-typedef struct __tb_aice_sendf_t
-{
- /// the file
- tb_file_ref_t file;
-
- /// the private data for using the left space of the union
- tb_handle_t priv[1];
-
- /// the real
- tb_size_t real;
-
- /// the size
- tb_hize_t size;
-
- /// the seek
- tb_hize_t seek;
-
-}tb_aice_sendf_t;
-
-/// the readv aice type
-typedef struct __tb_aice_readv_t
-{
- /// the read list
- tb_iovec_t const* list;
-
- /// the list size
- tb_size_t size;
-
- /// the data real
- tb_size_t real;
-
- /// the file seek
- tb_hize_t seek;
-
-}tb_aice_readv_t;
-
-/// the writv aice type
-typedef struct __tb_aice_writv_t
-{
- /// the writ list
- tb_iovec_t const* list;
-
- /// the list size
- tb_size_t size;
-
- /// the data real
- tb_size_t real;
-
- /// the file seek
- tb_hize_t seek;
-
-}tb_aice_writv_t;
-
-/// the runtask aice type
-typedef struct __tb_aice_runtask_t
-{
- /// the when
- tb_hize_t when;
-
- /// the delay
- tb_size_t delay;
-
-}tb_aice_runtask_t;
-
-/// the aice type
-typedef struct __tb_aice_t
-{
- /// the aice code
- tb_uint8_t code;
-
- /*! the state
- *
- * TB_STATE_OK
- * TB_STATE_FAILED
- * TB_STATE_KILLED
- * TB_STATE_CLOSED
- * TB_STATE_PENDING
- * TB_STATE_TIMEOUT
- * TB_STATE_NOT_SUPPORTED
- */
- tb_size_t state;
-
- /// the aico func
- tb_aico_func_t func;
-
- /// the aico private data
- tb_cpointer_t priv;
-
- /// the aico
- tb_aico_ref_t aico;
-
- /*! the events
- *
- * tb_iovec_t must be aligned by cpu-bytes for windows WSABUF
- */
-#ifdef TB_CONFIG_OS_WINDOWS
- __tb_cpu_aligned__ union
-#else
- union
-#endif
- {
- // for sock
- tb_aice_acpt_t acpt;
- tb_aice_conn_t conn;
- tb_aice_recv_t recv;
- tb_aice_send_t send;
- tb_aice_urecv_t urecv;
- tb_aice_usend_t usend;
- tb_aice_recvv_t recvv;
- tb_aice_sendv_t sendv;
- tb_aice_urecvv_t urecvv;
- tb_aice_usendv_t usendv;
- tb_aice_sendf_t sendf;
-
- // for file
- tb_aice_read_t read;
- tb_aice_writ_t writ;
- tb_aice_readv_t readv;
- tb_aice_writv_t writv;
-
- // for task
- tb_aice_runtask_t runtask;
-
- } u;
-
-}tb_aice_t, *tb_aice_ref_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/asio/deprecated/aico.c b/core/src/tbox/src/tbox/asio/deprecated/aico.c
deleted file mode 100644
index 2731f7015..000000000
--- a/core/src/tbox/src/tbox/asio/deprecated/aico.c
+++ /dev/null
@@ -1,1082 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file aico.c
- * @ingroup asio
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "aico"
-#define TB_TRACE_MODULE_DEBUG (1)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "aico.h"
-#include "aicp.h"
-#include "impl/prefix.h"
-#include "../../platform/platform.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_aico_ref_t tb_aico_init(tb_aicp_ref_t aicp)
-{
- // check
- tb_aicp_impl_t* aicp_impl = (tb_aicp_impl_t*)aicp;
- tb_assert_and_check_return_val(aicp_impl && aicp_impl->pool, tb_null);
-
- // enter
- tb_spinlock_enter(&aicp_impl->lock);
-
- // make aico
- tb_aico_impl_t* aico = (tb_aico_impl_t*)tb_fixed_pool_malloc0(aicp_impl->pool);
-
- // init aico
- if (aico)
- {
- aico->aicp = aicp;
- aico->type = TB_AICO_TYPE_NONE;
- aico->handle = tb_null;
- aico->state = TB_STATE_CLOSED;
-
- // init timeout
- tb_size_t i = 0;
- tb_size_t n = tb_arrayn(aico->timeout);
- for (i = 0; i < n; i++) aico->timeout[i] = -1;
- }
-
- // leave
- tb_spinlock_leave(&aicp_impl->lock);
-
- // ok?
- return (tb_aico_ref_t)aico;
-}
-tb_bool_t tb_aico_open_sock(tb_aico_ref_t aico, tb_socket_ref_t sock)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_aicp_impl_t* aicp_impl = (tb_aicp_impl_t*)impl->aicp;
- tb_assert_and_check_return_val(impl && sock && aicp_impl && aicp_impl->ptor && aicp_impl->ptor->addo, tb_false);
-
- // done
- tb_bool_t ok = tb_false;
- do
- {
- // closed?
- tb_assert_and_check_break(tb_atomic_get(&impl->state) == TB_STATE_CLOSED);
- tb_assert_and_check_break(!impl->type && !impl->handle);
-
- // bind type and handle
- impl->type = TB_AICO_TYPE_SOCK;
- impl->handle = (tb_handle_t)sock;
-
- // addo aico
- ok = aicp_impl->ptor->addo(aicp_impl->ptor, impl);
- tb_assert_and_check_break(ok);
-
- // opened
- tb_atomic_set(&impl->state, TB_STATE_OPENED);
-
- } while (0);
-
- // ok?
- return ok;
-}
-tb_bool_t tb_aico_open_sock_from_type(tb_aico_ref_t aico, tb_size_t type, tb_size_t family)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_aicp_impl_t* aicp_impl = (tb_aicp_impl_t*)impl->aicp;
- tb_assert_and_check_return_val(impl && aicp_impl && aicp_impl->ptor && aicp_impl->ptor->addo, tb_false);
-
- // done
- tb_bool_t ok = tb_false;
- tb_socket_ref_t sock = tb_null;
- do
- {
- // closed?
- tb_assert_and_check_break(tb_atomic_get(&impl->state) == TB_STATE_CLOSED);
- tb_assert_and_check_break(!impl->type && !impl->handle);
-
- // init sock
- sock = tb_socket_init(type, family);
- tb_assert_and_check_break(sock);
-
- // bind type and handle
- impl->type = TB_AICO_TYPE_SOCK;
- impl->handle = (tb_handle_t)sock;
-
- // addo aico
- ok = aicp_impl->ptor->addo(aicp_impl->ptor, impl);
- tb_assert_and_check_break(ok);
-
- // opened
- tb_atomic_set(&impl->state, TB_STATE_OPENED);
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (sock) tb_socket_exit(sock);
- sock = tb_null;
- }
-
- // ok?
- return ok;
-}
-tb_bool_t tb_aico_open_file(tb_aico_ref_t aico, tb_file_ref_t file)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_aicp_impl_t* aicp_impl = (tb_aicp_impl_t*)impl->aicp;
- tb_assert_and_check_return_val(impl && file && aicp_impl && aicp_impl->ptor && aicp_impl->ptor->addo, tb_false);
-
- // done
- tb_bool_t ok = tb_false;
- do
- {
- // closed?
- tb_assert_and_check_break(tb_atomic_get(&impl->state) == TB_STATE_CLOSED);
- tb_assert_and_check_break(!impl->type && !impl->handle);
-
- // bind type and handle
- impl->type = TB_AICO_TYPE_FILE;
- impl->handle = (tb_handle_t)file;
-
- // addo aico
- ok = aicp_impl->ptor->addo(aicp_impl->ptor, impl);
- tb_assert_and_check_break(ok);
-
- // opened
- tb_atomic_set(&impl->state, TB_STATE_OPENED);
-
- } while (0);
-
- // ok?
- return ok;
-}
-tb_bool_t tb_aico_open_file_from_path(tb_aico_ref_t aico, tb_char_t const* path, tb_size_t mode)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_aicp_impl_t* aicp_impl = (tb_aicp_impl_t*)impl->aicp;
- tb_assert_and_check_return_val(impl && path && aicp_impl && aicp_impl->ptor && aicp_impl->ptor->addo, tb_false);
-
- // done
- tb_bool_t ok = tb_false;
- tb_file_ref_t file = tb_null;
- do
- {
- // closed?
- tb_assert_and_check_break(tb_atomic_get(&impl->state) == TB_STATE_CLOSED);
- tb_assert_and_check_break(!impl->type && !impl->handle);
-
- // init file
- file = tb_file_init(path, mode | TB_FILE_MODE_ASIO);
- tb_assert_and_check_break(file);
-
- // bind type and handle
- impl->type = TB_AICO_TYPE_FILE;
- impl->handle = (tb_handle_t)file;
-
- // addo aico
- ok = aicp_impl->ptor->addo(aicp_impl->ptor, impl);
- tb_assert_and_check_break(ok);
-
- // opened
- tb_atomic_set(&impl->state, TB_STATE_OPENED);
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (file) tb_file_exit(file);
- file = tb_null;
- }
-
- // ok?
- return ok;
-}
-tb_bool_t tb_aico_open_task(tb_aico_ref_t aico, tb_bool_t ltimer)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_aicp_impl_t* aicp_impl = (tb_aicp_impl_t*)impl->aicp;
- tb_assert_and_check_return_val(impl && aicp_impl && aicp_impl->ptor && aicp_impl->ptor->addo, tb_false);
-
- // done
- tb_bool_t ok = tb_false;
- do
- {
- // closed?
- tb_assert_and_check_break(tb_atomic_get(&impl->state) == TB_STATE_CLOSED);
- tb_assert_and_check_break(!impl->type);
-
- // bind type and handle
- // hack: handle != null? using higher precision timer for being compatible with sock/file task
- impl->type = TB_AICO_TYPE_TASK;
- impl->handle = (tb_handle_t)(tb_size_t)!ltimer;
-
- // addo aico
- ok = aicp_impl->ptor->addo(aicp_impl->ptor, impl);
- tb_assert_and_check_break(ok);
-
- // opened
- tb_atomic_set(&impl->state, TB_STATE_OPENED);
-
- } while (0);
-
- // ok?
- return ok;
-}
-tb_void_t tb_aico_exit(tb_aico_ref_t aico)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_aicp_impl_t* aicp_impl = (tb_aicp_impl_t*)impl->aicp;
- tb_assert_and_check_return(impl && aicp_impl && aicp_impl->pool);
-
- // wait closing?
- tb_size_t tryn = 15;
- while (tb_atomic_get(&impl->state) != TB_STATE_CLOSED && tryn--)
- {
- // trace
- tb_trace_d("exit[%p]: type: %lu, handle: %p, state: %s: wait: ..", aico, tb_aico_type(aico), impl->handle, tb_state_cstr(tb_atomic_get(&impl->state)));
-
- // wait some time
- tb_msleep(200);
- }
-
- // check
- tb_assert(tb_atomic_get(&impl->state) == TB_STATE_CLOSED);
- tb_check_return(tb_atomic_get(&impl->state) == TB_STATE_CLOSED);
-
- // enter
- tb_spinlock_enter(&aicp_impl->lock);
-
- // trace
- tb_trace_d("exit[%p]: type: %lu, handle: %p, state: %s: ok", aico, tb_aico_type(aico), impl->handle, tb_state_cstr(tb_atomic_get(&impl->state)));
-
- // free it
- tb_fixed_pool_free(aicp_impl->pool, aico);
-
- // leave
- tb_spinlock_leave(&aicp_impl->lock);
-}
-tb_void_t tb_aico_kill(tb_aico_ref_t aico)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_aicp_impl_t* aicp_impl = (tb_aicp_impl_t*)impl->aicp;
- tb_assert_and_check_return(impl && aicp_impl && aicp_impl->ptor && aicp_impl->ptor->kilo);
-
- // the impl is killed and not worked?
- tb_check_return(!tb_atomic_get(&aicp_impl->kill) || tb_atomic_get(&aicp_impl->work));
-
- // trace
- tb_trace_d("kill: aico[%p]: type: %lu, handle: %p: state: %s: ..", aico, tb_aico_type(aico), impl->handle, tb_state_cstr(tb_atomic_get(&((tb_aico_impl_t*)aico)->state)));
-
- // opened? killed
- if (TB_STATE_OPENED == tb_atomic_fetch_and_pset(&impl->state, TB_STATE_OPENED, TB_STATE_KILLED))
- {
- // trace
- tb_trace_d("kill: aico[%p]: type: %lu, handle: %p: ok", aico, tb_aico_type(aico), impl->handle);
- }
- // pending? kill it
- else if (TB_STATE_PENDING == tb_atomic_fetch_and_pset(&impl->state, TB_STATE_PENDING, TB_STATE_KILLING))
- {
- // kill aico
- aicp_impl->ptor->kilo(aicp_impl->ptor, impl);
-
- // trace
- tb_trace_d("kill: aico[%p]: type: %lu, handle: %p: state: pending: ok", aico, tb_aico_type(aico), impl->handle);
- }
-}
-tb_aicp_ref_t tb_aico_aicp(tb_aico_ref_t aico)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl, tb_null);
-
- // the impl aicp
- return impl->aicp;
-}
-tb_size_t tb_aico_type(tb_aico_ref_t aico)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl, TB_AICO_TYPE_NONE);
-
- // the impl type
- return impl->type;
-}
-tb_socket_ref_t tb_aico_sock(tb_aico_ref_t aico)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->type == TB_AICO_TYPE_SOCK, tb_null);
-
- // the socket handle
- return (tb_socket_ref_t)impl->handle;
-}
-tb_file_ref_t tb_aico_file(tb_aico_ref_t aico)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->type == TB_AICO_TYPE_FILE, tb_null);
-
- // the file handle
- return (tb_file_ref_t)impl->handle;
-}
-tb_long_t tb_aico_timeout(tb_aico_ref_t aico, tb_size_t type)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && type < tb_arrayn(impl->timeout), -1);
-
- // the impl timeout
- return tb_atomic_get((tb_atomic_t*)(impl->timeout + type));
-}
-tb_void_t tb_aico_timeout_set(tb_aico_ref_t aico, tb_size_t type, tb_long_t timeout)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return(impl && type < tb_arrayn(impl->timeout));
-
- // set the impl timeout
- tb_atomic_set((tb_atomic_t*)(impl->timeout + type), timeout);
-}
-tb_bool_t tb_aico_clos_try(tb_aico_ref_t aico)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp, tb_false);
-
- // closed?
- return (tb_atomic_get(&impl->state) == TB_STATE_CLOSED)? tb_true : tb_false;
-}
-tb_bool_t tb_aico_clos_(tb_aico_ref_t aico, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_CLOS;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
-
- // closed?
- if (tb_aico_clos_try(aico))
- {
- // close ok
- aice.state = TB_STATE_OK;
-
- // done func directly
- func(&aice);
-
- // ok
- return tb_true;
- }
-
- // post
- return tb_aicp_post_(impl->aicp, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_acpt_(tb_aico_ref_t aico, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_ACPT;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
-
- // post
- return tb_aicp_post_(impl->aicp, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_conn_(tb_aico_ref_t aico, tb_ipaddr_ref_t addr, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && addr, tb_false);
-
- // check address
- tb_assert(!tb_ipaddr_is_empty(addr));
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_CONN;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- tb_ipaddr_copy(&aice.u.conn.addr, addr);
-
- // post
- return tb_aicp_post_(impl->aicp, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_recv_(tb_aico_ref_t aico, tb_byte_t* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && data && size, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_RECV;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.recv.data = data;
- aice.u.recv.size = (tb_iovec_size_t)size;
-
- // post
- return tb_aicp_post_(impl->aicp, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_send_(tb_aico_ref_t aico, tb_byte_t const* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && data && size, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_SEND;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.send.data = data;
- aice.u.send.size = (tb_iovec_size_t)size;
-
- // post
- return tb_aicp_post_(impl->aicp, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_urecv_(tb_aico_ref_t aico, tb_byte_t* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && data && size, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_URECV;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.urecv.data = data;
- aice.u.urecv.size = (tb_iovec_size_t)size;
-
- // post
- return tb_aicp_post_(impl->aicp, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_usend_(tb_aico_ref_t aico, tb_ipaddr_ref_t addr, tb_byte_t const* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && addr && data && size, tb_false);
-
- // check address
- tb_assert(!tb_ipaddr_is_empty(addr));
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_USEND;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.usend.data = data;
- aice.u.usend.size = (tb_iovec_size_t)size;
- tb_ipaddr_copy(&aice.u.usend.addr, addr);
-
- // post
- return tb_aicp_post_(impl->aicp, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_recvv_(tb_aico_ref_t aico, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && list && size, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_RECVV;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.recvv.list = list;
- aice.u.recvv.size = size;
-
- // post
- return tb_aicp_post_(impl->aicp, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_sendv_(tb_aico_ref_t aico, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && list && size, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_SENDV;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.sendv.list = list;
- aice.u.sendv.size = size;
-
- // post
- return tb_aicp_post_(impl->aicp, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_urecvv_(tb_aico_ref_t aico, tb_ipaddr_ref_t addr, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && addr && list && size, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_URECVV;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.urecvv.list = list;
- aice.u.urecvv.size = size;
- tb_ipaddr_copy(&aice.u.urecvv.addr, addr);
-
- // post
- return tb_aicp_post_(impl->aicp, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_usendv_(tb_aico_ref_t aico, tb_ipaddr_ref_t addr, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && addr && list && size, tb_false);
-
- // check address
- tb_assert(!tb_ipaddr_is_empty(addr));
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_USENDV;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.usendv.list = list;
- aice.u.usendv.size = size;
- tb_ipaddr_copy(&aice.u.usendv.addr, addr);
-
- // post
- return tb_aicp_post_(impl->aicp, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_sendf_(tb_aico_ref_t aico, tb_file_ref_t file, tb_hize_t seek, tb_hize_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && file, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_SENDF;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.sendf.file = file;
- aice.u.sendf.seek = seek;
- aice.u.sendf.size = size;
-
- // post
- return tb_aicp_post_(impl->aicp, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_read_(tb_aico_ref_t aico, tb_hize_t seek, tb_byte_t* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && data && size, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_READ;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.read.seek = seek;
- aice.u.read.data = data;
- aice.u.read.size = (tb_iovec_size_t)size;
-
- // post
- return tb_aicp_post_(impl->aicp, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_writ_(tb_aico_ref_t aico, tb_hize_t seek, tb_byte_t const* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && data && size, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_WRIT;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.writ.seek = seek;
- aice.u.writ.data = data;
- aice.u.writ.size = (tb_iovec_size_t)size;
-
- // post
- return tb_aicp_post_(impl->aicp, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_readv_(tb_aico_ref_t aico, tb_hize_t seek, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && list && size, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_READV;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.readv.seek = seek;
- aice.u.readv.list = list;
- aice.u.readv.size = size;
-
- // post
- return tb_aicp_post_(impl->aicp, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_writv_(tb_aico_ref_t aico, tb_hize_t seek, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && list && size, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_WRITV;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.writv.seek = seek;
- aice.u.writv.list = list;
- aice.u.writv.size = size;
-
- // post
- return tb_aicp_post_(impl->aicp, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_fsync_(tb_aico_ref_t aico, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_FSYNC;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
-
- // post
- return tb_aicp_post_(impl->aicp, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_clos_after_(tb_aico_ref_t aico, tb_size_t delay, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_CLOS;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
-
- // post
- return tb_aicp_post_after_(impl->aicp, delay, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_acpt_after_(tb_aico_ref_t aico, tb_size_t delay, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_ACPT;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
-
- // post
- return tb_aicp_post_after_(impl->aicp, delay, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_conn_after_(tb_aico_ref_t aico, tb_size_t delay, tb_ipaddr_ref_t addr, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && addr, tb_false);
-
- // check address
- tb_assert(!tb_ipaddr_is_empty(addr));
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_CONN;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- tb_ipaddr_copy(&aice.u.conn.addr, addr);
-
- // post
- return tb_aicp_post_after_(impl->aicp, delay, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_recv_after_(tb_aico_ref_t aico, tb_size_t delay, tb_byte_t* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && data && size, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_RECV;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.recv.data = data;
- aice.u.recv.size = (tb_iovec_size_t)size;
-
- // post
- return tb_aicp_post_after_(impl->aicp, delay, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_send_after_(tb_aico_ref_t aico, tb_size_t delay, tb_byte_t const* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && data && size, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_SEND;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.send.data = data;
- aice.u.send.size = (tb_iovec_size_t)size;
-
- // post
- return tb_aicp_post_after_(impl->aicp, delay, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_urecv_after_(tb_aico_ref_t aico, tb_size_t delay, tb_byte_t* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && data && size, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_URECV;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.urecv.data = data;
- aice.u.urecv.size = (tb_iovec_size_t)size;
-
- // post
- return tb_aicp_post_after_(impl->aicp, delay, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_usend_after_(tb_aico_ref_t aico, tb_size_t delay, tb_ipaddr_ref_t addr, tb_byte_t const* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && addr && data && size, tb_false);
-
- // check address
- tb_assert(!tb_ipaddr_is_empty(addr));
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_USEND;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.usend.data = data;
- aice.u.usend.size = (tb_iovec_size_t)size;
- tb_ipaddr_copy(&aice.u.usend.addr, addr);
-
- // post
- return tb_aicp_post_after_(impl->aicp, delay, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_recvv_after_(tb_aico_ref_t aico, tb_size_t delay, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && list && size, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_RECVV;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.recvv.list = list;
- aice.u.recvv.size = size;
-
- // post
- return tb_aicp_post_after_(impl->aicp, delay, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_sendv_after_(tb_aico_ref_t aico, tb_size_t delay, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && list && size, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_SENDV;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.sendv.list = list;
- aice.u.sendv.size = size;
-
- // post
- return tb_aicp_post_after_(impl->aicp, delay, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_urecvv_after_(tb_aico_ref_t aico, tb_size_t delay, tb_ipaddr_ref_t addr, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && addr && list && size, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_URECVV;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.urecvv.list = list;
- aice.u.urecvv.size = size;
- tb_ipaddr_copy(&aice.u.urecvv.addr, addr);
-
- // post
- return tb_aicp_post_after_(impl->aicp, delay, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_usendv_after_(tb_aico_ref_t aico, tb_size_t delay, tb_ipaddr_ref_t addr, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && addr && list && size, tb_false);
-
- // check address
- tb_assert(!tb_ipaddr_is_empty(addr));
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_USENDV;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.usendv.list = list;
- aice.u.usendv.size = size;
- tb_ipaddr_copy(&aice.u.usendv.addr, addr);
-
- // post
- return tb_aicp_post_after_(impl->aicp, delay, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_sendf_after_(tb_aico_ref_t aico, tb_size_t delay, tb_file_ref_t file, tb_hize_t seek, tb_hize_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && file, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_SENDF;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.sendf.file = file;
- aice.u.sendf.seek = seek;
- aice.u.sendf.size = size;
-
- // post
- return tb_aicp_post_after_(impl->aicp, delay, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_read_after_(tb_aico_ref_t aico, tb_size_t delay, tb_hize_t seek, tb_byte_t* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && data && size, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_READ;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.read.seek = seek;
- aice.u.read.data = data;
- aice.u.read.size = (tb_iovec_size_t)size;
-
- // post
- return tb_aicp_post_after_(impl->aicp, delay, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_writ_after_(tb_aico_ref_t aico, tb_size_t delay, tb_hize_t seek, tb_byte_t const* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && data && size, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_WRIT;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.writ.seek = seek;
- aice.u.writ.data = data;
- aice.u.writ.size = (tb_iovec_size_t)size;
-
- // post
- return tb_aicp_post_after_(impl->aicp, delay, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_readv_after_(tb_aico_ref_t aico, tb_size_t delay, tb_hize_t seek, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && list && size, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_READV;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.readv.seek = seek;
- aice.u.readv.list = list;
- aice.u.readv.size = size;
-
- // post
- return tb_aicp_post_after_(impl->aicp, delay, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_writv_after_(tb_aico_ref_t aico, tb_size_t delay, tb_hize_t seek, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp && list && size, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_WRITV;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.writv.seek = seek;
- aice.u.writv.list = list;
- aice.u.writv.size = size;
-
- // post
- return tb_aicp_post_after_(impl->aicp, delay, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_fsync_after_(tb_aico_ref_t aico, tb_size_t delay, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_FSYNC;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
-
- // post
- return tb_aicp_post_after_(impl->aicp, delay, &aice __tb_debug_args__);
-}
-tb_bool_t tb_aico_task_run_(tb_aico_ref_t aico, tb_size_t delay, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__)
-{
- // check
- tb_aico_impl_t* impl = (tb_aico_impl_t*)aico;
- tb_assert_and_check_return_val(impl && impl->aicp, tb_false);
-
- // init
- tb_aice_t aice = {0};
- aice.code = TB_AICE_CODE_RUNTASK;
- aice.state = TB_STATE_PENDING;
- aice.func = func;
- aice.priv = priv;
- aice.aico = aico;
- aice.u.runtask.when = tb_cache_time_mclock() + delay;
- aice.u.runtask.delay = delay;
-
- // post
- return tb_aicp_post_(impl->aicp, &aice __tb_debug_args__);
-}
-
diff --git a/core/src/tbox/src/tbox/asio/deprecated/aico.h b/core/src/tbox/src/tbox/asio/deprecated/aico.h
deleted file mode 100644
index c7c32201d..000000000
--- a/core/src/tbox/src/tbox/asio/deprecated/aico.h
+++ /dev/null
@@ -1,733 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file aico.h
- * @ingroup asio
- *
- */
-#ifndef TB_ASIO_AICO_H
-#define TB_ASIO_AICO_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-#include "../../network/ipaddr.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-#define tb_aico_clos(aico, func, priv) tb_aico_clos_(aico, func, priv __tb_debug_vals__)
-#define tb_aico_acpt(aico, func, priv) tb_aico_acpt_(aico, func, priv __tb_debug_vals__)
-#define tb_aico_conn(aico, addr, func, priv) tb_aico_conn_(aico, addr, func, priv __tb_debug_vals__)
-#define tb_aico_recv(aico, data, size, func, priv) tb_aico_recv_(aico, data, size, func, priv __tb_debug_vals__)
-#define tb_aico_send(aico, data, size, func, priv) tb_aico_send_(aico, data, size, func, priv __tb_debug_vals__)
-#define tb_aico_urecv(aico, data, size, func, priv) tb_aico_urecv_(aico, data, size, func, priv __tb_debug_vals__)
-#define tb_aico_usend(aico, addr, data, size, func, priv) tb_aico_usend_(aico, addr, data, size, func, priv __tb_debug_vals__)
-#define tb_aico_recvv(aico, list, size, func, priv) tb_aico_recvv_(aico, list, size, func, priv __tb_debug_vals__)
-#define tb_aico_sendv(aico, list, size, func, priv) tb_aico_sendv_(aico, list, size, func, priv __tb_debug_vals__)
-#define tb_aico_urecvv(aico, addr, list, size, func, priv) tb_aico_urecvv_(aico, addr, list, size, func, priv __tb_debug_vals__)
-#define tb_aico_usendv(aico, addr, list, size, func, priv) tb_aico_usendv_(aico, addr, list, size, func, priv __tb_debug_vals__)
-#define tb_aico_sendf(aico, file, seek, size, func, priv) tb_aico_sendf_(aico, file, seek, size, func, priv __tb_debug_vals__)
-#define tb_aico_read(aico, seek, data, size, func, priv) tb_aico_read_(aico, seek, data, size, func, priv __tb_debug_vals__)
-#define tb_aico_writ(aico, seek, data, size, func, priv) tb_aico_writ_(aico, seek, data, size, func, priv __tb_debug_vals__)
-#define tb_aico_readv(aico, seek, list, size, func, priv) tb_aico_readv_(aico, seek, list, size, func, priv __tb_debug_vals__)
-#define tb_aico_writv(aico, seek, list, size, func, priv) tb_aico_writv_(aico, seek, list, size, func, priv __tb_debug_vals__)
-#define tb_aico_fsync(aico, func, priv) tb_aico_fsync_(aico, func, priv __tb_debug_vals__)
-
-#define tb_aico_clos_after(aico, delay, func, priv) tb_aico_clos_after_(aico, delay, func, priv __tb_debug_vals__)
-#define tb_aico_acpt_after(aico, delay, func, priv) tb_aico_acpt_after_(aico, delay, func, priv __tb_debug_vals__)
-#define tb_aico_conn_after(aico, delay, addr, func, priv) tb_aico_conn_after_(aico, delay, addr, func, priv __tb_debug_vals__)
-#define tb_aico_recv_after(aico, delay, data, size, func, priv) tb_aico_recv_after_(aico, delay, data, size, func, priv __tb_debug_vals__)
-#define tb_aico_send_after(aico, delay, data, size, func, priv) tb_aico_send_after_(aico, delay, data, size, func, priv __tb_debug_vals__)
-#define tb_aico_urecv_after(aico, delay, data, size, func, priv) tb_aico_urecv_after_(aico, delay, data, size, func, priv __tb_debug_vals__)
-#define tb_aico_usend_after(aico, delay, addr, data, size, func, priv) tb_aico_usend_after_(aico, delay, addr, data, size, func, priv __tb_debug_vals__)
-#define tb_aico_recvv_after(aico, delay, list, size, func, priv) tb_aico_recvv_after_(aico, delay, list, size, func, priv __tb_debug_vals__)
-#define tb_aico_sendv_after(aico, delay, list, size, func, priv) tb_aico_sendv_after_(aico, delay, list, size, func, priv __tb_debug_vals__)
-#define tb_aico_urecvv_after(aico, delay, addr, list, size, func, priv) tb_aico_urecvv_after_(aico, delay, addr, list, size, func, priv __tb_debug_vals__)
-#define tb_aico_usendv_after(aico, delay, addr, list, size, func, priv) tb_aico_usendv_after_(aico, delay, addr, list, size, func, priv __tb_debug_vals__)
-#define tb_aico_sendf_after(aico, delay, file, seek, size, func, priv) tb_aico_sendf_after_(aico, delay, file, seek, size, func, priv __tb_debug_vals__)
-#define tb_aico_read_after(aico, delay, seek, data, size, func, priv) tb_aico_read_after_(aico, delay, seek, data, size, func, priv __tb_debug_vals__)
-#define tb_aico_writ_after(aico, delay, seek, data, size, func, priv) tb_aico_writ_after_(aico, delay, seek, data, size, func, priv __tb_debug_vals__)
-#define tb_aico_readv_after(aico, delay, seek, list, size, func, priv) tb_aico_readv_after_(aico, delay, seek, list, size, func, priv __tb_debug_vals__)
-#define tb_aico_writv_after(aico, delay, seek, list, size, func, priv) tb_aico_writv_after_(aico, delay, seek, list, size, func, priv __tb_debug_vals__)
-#define tb_aico_fsync_after(aico, delay, func, priv) tb_aico_fsync_after_(aico, delay, func, priv __tb_debug_vals__)
-
-#define tb_aico_task_run(aico, delay, func, priv) tb_aico_task_run_(aico, delay, func, priv __tb_debug_vals__)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-struct __tb_aice_t;
-/// the aico func type
-typedef tb_bool_t (*tb_aico_func_t)(struct __tb_aice_t* aice);
-
-/// the aico type enum
-typedef enum __tb_aico_type_e
-{
- TB_AICO_TYPE_NONE = 0 //!< null
-, TB_AICO_TYPE_SOCK = 1 //!< sock
-, TB_AICO_TYPE_FILE = 2 //!< file
-, TB_AICO_TYPE_TASK = 3 //!< task
-, TB_AICO_TYPE_MAXN = 4
-
-}tb_aico_type_e;
-
-/// the aico timeout enum, only for sock
-typedef enum __tb_aico_timeout_e
-{
- TB_AICO_TIMEOUT_CONN = 0
-, TB_AICO_TIMEOUT_RECV = 1
-, TB_AICO_TIMEOUT_SEND = 2
-, TB_AICO_TIMEOUT_MAXN = 3
-
-}tb_aico_timeout_e;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init the aico
- *
- * @param aicp the aicp
- *
- * @return the aico
- */
-__tb_deprecated__
-tb_aico_ref_t tb_aico_init(tb_aicp_ref_t aicp);
-
-/*! open the sock aico
- *
- * @param aicp the aicp
- * @param sock the socket
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_open_sock(tb_aico_ref_t aico, tb_socket_ref_t sock);
-
-/*! open the sock aico from the socket type
- *
- * @param aicp the aicp
- * @param type the socket type
- * @param family the address family, default: ipv4
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_open_sock_from_type(tb_aico_ref_t aico, tb_size_t type, tb_size_t family);
-
-/*! open the file aico
- *
- * @param aicp the aicp
- * @param file the file
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_open_file(tb_aico_ref_t aico, tb_file_ref_t file);
-
-/*! open the file aico from path
- *
- * @param aicp the aicp
- * @param path the file path
- * @param mode the file mode
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_open_file_from_path(tb_aico_ref_t aico, tb_char_t const* path, tb_size_t mode);
-
-/*! open the task aico
- *
- * @param aicp the aicp
- * @param ltimer is the lower precision timer?
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_open_task(tb_aico_ref_t aico, tb_bool_t ltimer);
-
-/*! kill the aico
- *
- * @param aico the aico
- */
-__tb_deprecated__
-tb_void_t tb_aico_kill(tb_aico_ref_t aico);
-
-/*! exit the aico
- *
- * @param aico the aico
- */
-__tb_deprecated__
-tb_void_t tb_aico_exit(tb_aico_ref_t aico);
-
-/*! the aico aicp
- *
- * @param aico the aico
- *
- * @return the aico aicp
- */
-__tb_deprecated__
-tb_aicp_ref_t tb_aico_aicp(tb_aico_ref_t aico);
-
-/*! the aico type
- *
- * @param aico the aico
- *
- * @return the aico type
- */
-__tb_deprecated__
-tb_size_t tb_aico_type(tb_aico_ref_t aico);
-
-/*! get the socket if the aico is socket type
- *
- * @param aico the aico
- *
- * @return the socket
- */
-__tb_deprecated__
-tb_socket_ref_t tb_aico_sock(tb_aico_ref_t aico);
-
-/*! get the file if the aico is file type
- *
- * @param aico the aico
- *
- * @return the file
- */
-__tb_deprecated__
-tb_file_ref_t tb_aico_file(tb_aico_ref_t aico);
-
-/*! try to close it
- *
- * @param aico the aico
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_clos_try(tb_aico_ref_t aico);
-
-/*! the aico timeout
- *
- * @param aico the aico
- * @param type the timeout type
- *
- * @return the timeout
- */
-__tb_deprecated__
-tb_long_t tb_aico_timeout(tb_aico_ref_t aico, tb_size_t type);
-
-/*! set the aico timeout
- *
- * @param aico the aico
- * @param type the timeout type
- * @param timeout the timeout
- */
-__tb_deprecated__
-tb_void_t tb_aico_timeout_set(tb_aico_ref_t aico, tb_size_t type, tb_long_t timeout);
-
-/*! post the clos
- *
- * @param aicp the aicp
- * @param func the func
- * @param priv the func private data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_clos_(tb_aico_ref_t aico, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the acpt
- *
- * @param aico the aico
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_acpt_(tb_aico_ref_t aico, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the conn
- *
- * @param aico the aico
- * @param addr the address
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_conn_(tb_aico_ref_t aico, tb_ipaddr_ref_t addr, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the recv for sock
- *
- * @param aico the aico
- * @param data the data
- * @param size the size
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_recv_(tb_aico_ref_t aico, tb_byte_t* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the send for sock
- *
- * @param aico the aico
- * @param data the data
- * @param size the size, send the left file data if size == 0
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_send_(tb_aico_ref_t aico, tb_byte_t const* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the urecv for sock
- *
- * @param aico the aico
- * @param data the data
- * @param size the size
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_urecv_(tb_aico_ref_t aico, tb_byte_t* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the usend for sock
- *
- * @param aico the aico
- * @param addr the addr
- * @param data the data
- * @param size the size, send the left file data if size == 0
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_usend_(tb_aico_ref_t aico, tb_ipaddr_ref_t addr, tb_byte_t const* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the recvv for sock
- *
- * @param aico the aico
- * @param list the list
- * @param size the size
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_recvv_(tb_aico_ref_t aico, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the sendv for sock
- *
- * @param aico the aico
- * @param list the list
- * @param size the size
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_sendv_(tb_aico_ref_t aico, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the urecvv for sock
- *
- * @param aico the aico
- * @param addr the addr
- * @param list the list
- * @param size the size
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_urecvv_(tb_aico_ref_t aico, tb_ipaddr_ref_t addr, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the usendv for sock
- *
- * @param aico the aico
- * @param addr the addr
- * @param list the list
- * @param size the size
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_usendv_(tb_aico_ref_t aico, tb_ipaddr_ref_t addr, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the sendfile for sock
- *
- * @param aico the aico
- * @param file the file handle
- * @param seek the seek
- * @param size the size, send the left data if size == 0
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_sendf_(tb_aico_ref_t aico, tb_file_ref_t file, tb_hize_t seek, tb_hize_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the read for file
- *
- * @param aico the aico
- * @param seek the seek
- * @param data the data
- * @param size the size
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_read_(tb_aico_ref_t aico, tb_hize_t seek, tb_byte_t* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the writ for file
- *
- * @param aico the aico
- * @param seek the seek
- * @param data the data
- * @param size the size
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_writ_(tb_aico_ref_t aico, tb_hize_t seek, tb_byte_t const* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the readv for file
- *
- * @param aico the aico
- * @param seek the seek
- * @param list the list
- * @param size the size
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_readv_(tb_aico_ref_t aico, tb_hize_t seek, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the writv for file
- *
- * @param aico the aico
- * @param seek the seek
- * @param list the list
- * @param size the size
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_writv_(tb_aico_ref_t aico, tb_hize_t seek, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the fsync for file
- *
- * @param aico the aico
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_fsync_(tb_aico_ref_t aico, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the clos after the delay time
- *
- * @param aico the aico
- * @param delay the delay time, ms
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_clos_after_(tb_aico_ref_t aico, tb_size_t delay, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the acpt after the delay time
- *
- * @param aico the aico
- * @param delay the delay time, ms
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_acpt_after_(tb_aico_ref_t aico, tb_size_t delay, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the conn after the delay time
- *
- * @param aico the aico
- * @param delay the delay time, ms
- * @param addr the address
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_conn_after_(tb_aico_ref_t aico, tb_size_t delay, tb_ipaddr_ref_t addr, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the recv for sock after the delay time
- *
- * @param aico the aico
- * @param delay the delay time, ms
- * @param data the data
- * @param size the size
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_recv_after_(tb_aico_ref_t aico, tb_size_t delay, tb_byte_t* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the send for sock after the delay time
- *
- * @param aico the aico
- * @param delay the delay time, ms
- * @param data the data
- * @param size the size, send the left file data if size == 0
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_send_after_(tb_aico_ref_t aico, tb_size_t delay, tb_byte_t const* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the urecv for sock after the delay time
- *
- * @param aico the aico
- * @param delay the delay time, ms
- * @param data the data
- * @param size the size
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_urecv_after_(tb_aico_ref_t aico, tb_size_t delay, tb_byte_t* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the usend for sock after the delay time
- *
- * @param aico the aico
- * @param delay the delay time, ms
- * @param addr the addr
- * @param data the data
- * @param size the size, send the left file data if size == 0
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_usend_after_(tb_aico_ref_t aico, tb_size_t delay, tb_ipaddr_ref_t addr, tb_byte_t const* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the recvv for sock after the delay time
- *
- * @param aico the aico
- * @param delay the delay time, ms
- * @param list the list
- * @param size the size
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_recvv_after_(tb_aico_ref_t aico, tb_size_t delay, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the sendv for sock after the delay time
- *
- * @param aico the aico
- * @param delay the delay time, ms
- * @param list the list
- * @param size the size
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_sendv_after_(tb_aico_ref_t aico, tb_size_t delay, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the urecvv for sock after the delay time
- *
- * @param aico the aico
- * @param delay the delay time, ms
- * @param addr the addr
- * @param list the list
- * @param size the size
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_urecvv_after_(tb_aico_ref_t aico, tb_size_t delay, tb_ipaddr_ref_t addr, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the usendv for sock after the delay time
- *
- * @param aico the aico
- * @param delay the delay time, ms
- * @param addr the addr
- * @param list the list
- * @param size the size
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_usendv_after_(tb_aico_ref_t aico, tb_size_t delay, tb_ipaddr_ref_t addr, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the sendfile for sock after the delay time
- *
- * @param aico the aico
- * @param delay the delay time, ms
- * @param file the file handle
- * @param seek the seek
- * @param size the size, send the left data if size == 0
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_sendf_after_(tb_aico_ref_t aico, tb_size_t delay, tb_file_ref_t file, tb_hize_t seek, tb_hize_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the read for file after the delay time
- *
- * @param aico the aico
- * @param delay the delay time, ms
- * @param seek the seek
- * @param data the data
- * @param size the size
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_read_after_(tb_aico_ref_t aico, tb_size_t delay, tb_hize_t seek, tb_byte_t* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the writ for file after the delay time
- *
- * @param aico the aico
- * @param delay the delay time, ms
- * @param seek the seek
- * @param data the data
- * @param size the size
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_writ_after_(tb_aico_ref_t aico, tb_size_t delay, tb_hize_t seek, tb_byte_t const* data, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the readv for file after the delay time
- *
- * @param aico the aico
- * @param delay the delay time, ms
- * @param seek the seek
- * @param list the list
- * @param size the size
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_readv_after_(tb_aico_ref_t aico, tb_size_t delay, tb_hize_t seek, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the writv for file after the delay time
- *
- * @param aico the aico
- * @param delay the delay time, ms
- * @param seek the seek
- * @param list the list
- * @param size the size
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_writv_after_(tb_aico_ref_t aico, tb_size_t delay, tb_hize_t seek, tb_iovec_t const* list, tb_size_t size, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! post the fsync for file after the delay time
- *
- * @param aico the aico
- * @param delay the delay time, ms
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_fsync_after_(tb_aico_ref_t aico, tb_size_t delay, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/*! run aico task after timeout and will be auto-remove it after be expired
- *
- * only once, need continue to call it again if want to repeat task
- *
- * @param aico the aico
- * @param delay the delay time, ms
- * @param func the callback func
- * @param priv the callback data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aico_task_run_(tb_aico_ref_t aico, tb_size_t delay, tb_aico_func_t func, tb_cpointer_t priv __tb_debug_decl__);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/asio/deprecated/aicp.c b/core/src/tbox/src/tbox/asio/deprecated/aicp.c
deleted file mode 100644
index d4373391b..000000000
--- a/core/src/tbox/src/tbox/asio/deprecated/aicp.c
+++ /dev/null
@@ -1,596 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file aicp.c
- * @ingroup asio
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "aicp"
-#define TB_TRACE_MODULE_DEBUG (1)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "aicp.h"
-#include "aico.h"
-#include "impl/prefix.h"
-#include "../../math/math.h"
-#include "../../utils/utils.h"
-#include "../../memory/memory.h"
-#include "../../platform/platform.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * private implementation
- */
-static tb_bool_t tb_aicp_walk_wait(tb_pointer_t item, tb_cpointer_t priv)
-{
- // check
- tb_aico_impl_t* aico = (tb_aico_impl_t*)item;
- tb_assert_and_check_return_val(aico, tb_false);
-
- // trace
-#ifdef __tb_debug__
- tb_trace_e("aico[%p]: wait exited failed, type: %lu, handle: %p, state: %s for func: %s, line: %lu, file: %s", aico, tb_aico_type((tb_aico_ref_t)aico), aico->handle, tb_state_cstr(tb_atomic_get(&aico->state)), aico->func, aico->line, aico->file);
-#else
- tb_trace_e("aico[%p]: wait exited failed, type: %lu, handle: %p, state: %s", aico, tb_aico_type((tb_aico_ref_t)aico), aico->handle, tb_state_cstr(tb_atomic_get(&aico->state)));
-#endif
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_aicp_walk_kill(tb_pointer_t item, tb_cpointer_t priv)
-{
- // check
- tb_aico_impl_t* aico = (tb_aico_impl_t*)item;
- tb_assert_and_check_return_val(aico, tb_false);
-
- // kill it
- tb_aico_kill((tb_aico_ref_t)aico);
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_aicp_post_after_func(tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(aice && aice->aico && aice->code == TB_AICE_CODE_RUNTASK, tb_false);
-
- // the posted aice
- tb_aice_ref_t posted_aice = (tb_aice_ref_t)aice->priv;
- tb_assert_and_check_return_val(posted_aice && posted_aice->aico, tb_false);
-
- // the impl
- tb_aicp_impl_t* impl = (tb_aicp_impl_t*)tb_aico_aicp(aice->aico);
- tb_assert_and_check_return_val(impl && impl->ptor && impl->ptor->post, tb_false);
-
- // ok?
- tb_bool_t ok = tb_true;
- tb_bool_t posted = tb_true;
- if (aice->state == TB_STATE_OK)
- {
- // post it
-#ifdef __tb_debug__
- if (!tb_aicp_post_((tb_aicp_ref_t)impl, posted_aice, ((tb_aico_impl_t*)aice->aico)->func, ((tb_aico_impl_t*)aice->aico)->line, ((tb_aico_impl_t*)aice->aico)->file))
-#else
- if (!tb_aicp_post_((tb_aicp_ref_t)impl, posted_aice))
-#endif
- {
- // not posted
- posted = tb_false;
-
- // failed
- posted_aice->state = TB_STATE_FAILED;
- }
- }
- // failed?
- else
- {
- // not posted
- posted = tb_false;
-
- // save state
- posted_aice->state = aice->state;
- }
-
- // not posted? done func now
- if (!posted)
- {
- // done func: notify failed
- if (posted_aice->func && !posted_aice->func(posted_aice)) ok = tb_false;
- }
-
- // exit the posted aice
- tb_free(posted_aice);
-
- // ok?
- return ok;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * instance implementation
- */
-static tb_int_t tb_aicp_instance_loop(tb_cpointer_t priv)
-{
- // aicp
- tb_aicp_ref_t aicp = (tb_aicp_ref_t)priv;
-
- // trace
- tb_trace_d("loop: init");
-
- // loop aicp
- if (aicp) tb_aicp_loop(aicp);
-
- // trace
- tb_trace_d("loop: exit");
-
- // exit
- return 0;
-}
-static tb_handle_t tb_aicp_instance_init(tb_cpointer_t* ppriv)
-{
- // check
- tb_assert_and_check_return_val(ppriv, tb_null);
-
- // done
- tb_bool_t ok = tb_false;
- tb_aicp_ref_t aicp = tb_null;
- do
- {
- // init aicp
- aicp = tb_aicp_init(0);
- tb_assert_and_check_break(aicp);
-
- // init loop
- *ppriv = (tb_cpointer_t)tb_thread_init(tb_null, tb_aicp_instance_loop, aicp, 0);
- tb_assert_and_check_break(*ppriv);
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit aicp
- if (aicp) tb_aicp_exit(aicp);
- aicp = tb_null;
- }
-
- // ok?
- return (tb_handle_t)aicp;
-}
-static tb_void_t tb_aicp_instance_exit(tb_handle_t handle, tb_cpointer_t priv)
-{
- // check
- tb_assert_and_check_return(handle);
-
- // wait all
- if (!tb_aicp_wait_all((tb_aicp_ref_t)handle, 5000)) return ;
-
- // kill aicp
- tb_aicp_kill((tb_aicp_ref_t)handle);
-
- // exit loop
- tb_thread_ref_t loop = (tb_thread_ref_t)priv;
- if (loop)
- {
- // wait it
- if (!tb_thread_wait(loop, 5000, tb_null)) return ;
-
- // exit it
- tb_thread_exit(loop);
- }
-
- // exit it
- tb_aicp_exit((tb_aicp_ref_t)handle);
-}
-static tb_void_t tb_aicp_instance_kill(tb_handle_t handle, tb_cpointer_t priv)
-{
- // check
- tb_assert_and_check_return(handle);
-
- // kill all
- tb_aicp_kill_all((tb_aicp_ref_t)handle);
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_aicp_ref_t tb_aicp()
-{
- return (tb_aicp_ref_t)tb_singleton_instance(TB_SINGLETON_TYPE_AICP, tb_aicp_instance_init, tb_aicp_instance_exit, tb_aicp_instance_kill, tb_null);
-}
-tb_aicp_ref_t tb_aicp_init(tb_size_t maxn)
-{
- // check iovec
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_recv_t, data, tb_iovec_t, data), tb_null);
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_recv_t, size, tb_iovec_t, size), tb_null);
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_send_t, data, tb_iovec_t, data), tb_null);
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_send_t, size, tb_iovec_t, size), tb_null);
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_read_t, data, tb_iovec_t, data), tb_null);
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_read_t, size, tb_iovec_t, size), tb_null);
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_writ_t, data, tb_iovec_t, data), tb_null);
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_writ_t, size, tb_iovec_t, size), tb_null);
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_urecv_t, data, tb_iovec_t, data), tb_null);
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_urecv_t, size, tb_iovec_t, size), tb_null);
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_usend_t, data, tb_iovec_t, data), tb_null);
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_usend_t, size, tb_iovec_t, size), tb_null);
-
- // check real
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_recv_t, real, tb_aice_send_t, real), tb_null);
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_recv_t, real, tb_aice_read_t, real), tb_null);
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_recv_t, real, tb_aice_writ_t, real), tb_null);
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_recv_t, real, tb_aice_sendf_t, real), tb_null);
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_recv_t, real, tb_aice_sendv_t, real), tb_null);
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_recv_t, real, tb_aice_recvv_t, real), tb_null);
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_recv_t, real, tb_aice_readv_t, real), tb_null);
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_recv_t, real, tb_aice_writv_t, real), tb_null);
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_recv_t, real, tb_aice_urecv_t, real), tb_null);
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_recv_t, real, tb_aice_usend_t, real), tb_null);
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_recv_t, real, tb_aice_urecvv_t, real), tb_null);
- tb_assert_and_check_return_val(tb_memberof_eq(tb_aice_recv_t, real, tb_aice_usendv_t, real), tb_null);
-
- // done
- tb_bool_t ok = tb_false;
- tb_aicp_impl_t* impl = tb_null;
- do
- {
- // make impl
- impl = tb_malloc0_type(tb_aicp_impl_t);
- tb_assert_and_check_break(impl);
-
- // init impl
-#ifdef __tb_small__
- impl->maxn = maxn? maxn : (1 << 4);
-#else
- impl->maxn = maxn? maxn : (1 << 8);
-#endif
-
- // init lock
- if (!tb_spinlock_init(&impl->lock)) break;
-
- // init proactor
- impl->ptor = tb_aicp_ptor_impl_init(impl);
- tb_assert_and_check_break(impl->ptor && impl->ptor->step >= sizeof(tb_aico_impl_t));
-
- // init aico pool
- impl->pool = tb_fixed_pool_init(tb_null, (impl->maxn >> 4) + 16, impl->ptor->step, tb_null, tb_null, tb_null);
- tb_assert_and_check_break(impl->pool);
-
- // register lock profiler
-#ifdef TB_LOCK_PROFILER_ENABLE
- tb_lock_profiler_register(tb_lock_profiler(), (tb_pointer_t)&impl->lock, TB_TRACE_MODULE_NAME);
-#endif
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit impl
- if (impl) tb_aicp_exit((tb_aicp_ref_t)impl);
- impl = tb_null;
- }
-
- // ok?
- return (tb_aicp_ref_t)impl;
-}
-tb_bool_t tb_aicp_exit(tb_aicp_ref_t aicp)
-{
- // check
- tb_aicp_impl_t* impl = (tb_aicp_impl_t*)aicp;
- tb_assert_and_check_return_val(impl, tb_false);
-
- // kill all first
- tb_aicp_kill_all((tb_aicp_ref_t)impl);
-
- // wait all exiting
- if (tb_aicp_wait_all((tb_aicp_ref_t)impl, 5000) <= 0)
- {
- // wait failed, trace left aicos
- tb_spinlock_enter(&impl->lock);
- if (impl->pool) tb_fixed_pool_walk(impl->pool, tb_aicp_walk_wait, tb_null);
- tb_spinlock_leave(&impl->lock);
- return tb_false;
- }
-
- // kill loop
- tb_aicp_kill((tb_aicp_ref_t)impl);
-
- // wait workers exiting
- tb_hong_t time = tb_mclock();
- while (tb_atomic_get(&impl->work) && (tb_mclock() < time + 5000)) tb_msleep(500);
-
- // exit proactor
- if (impl->ptor)
- {
- tb_assert(impl->ptor && impl->ptor->exit);
- impl->ptor->exit(impl->ptor);
- impl->ptor = tb_null;
- }
-
- // exit aico pool
- tb_spinlock_enter(&impl->lock);
- if (impl->pool) tb_fixed_pool_exit(impl->pool);
- impl->pool = tb_null;
- tb_spinlock_leave(&impl->lock);
-
- // exit lock
- tb_spinlock_exit(&impl->lock);
-
- // free impl
- tb_free(impl);
-
- // ok
- return tb_true;
-}
-tb_size_t tb_aicp_maxn(tb_aicp_ref_t aicp)
-{
- // check
- tb_aicp_impl_t* impl = (tb_aicp_impl_t*)aicp;
- tb_assert_and_check_return_val(impl, 0);
-
- // the maxn
- return impl->maxn;
-}
-tb_bool_t tb_aicp_post_(tb_aicp_ref_t aicp, tb_aice_ref_t aice __tb_debug_decl__)
-{
- // check
- tb_aicp_impl_t* impl = (tb_aicp_impl_t*)aicp;
- tb_assert_and_check_return_val(impl && impl->ptor && impl->ptor->post, tb_false);
- tb_assert_and_check_return_val(aice && aice->aico, tb_false);
-
- // the aico
- tb_aico_impl_t* aico = (tb_aico_impl_t*)aice->aico;
- tb_assert_and_check_return_val(aico, tb_false);
-
- // opened or killed or closed? pending it
- tb_size_t state = tb_atomic_fetch_and_pset(&aico->state, TB_STATE_OPENED, TB_STATE_PENDING);
- if (state == TB_STATE_OPENED || state == TB_STATE_KILLED)
- {
- // save debug info
-#ifdef __tb_debug__
- aico->func = func_;
- aico->file = file_;
- aico->line = line_;
-#endif
-
- // post aice
- return impl->ptor->post(impl->ptor, aice);
- }
-
- // trace
-#ifdef __tb_debug__
- tb_trace_e("post aice[%lu] failed, the aico[%p]: type: %lu, handle: %p, state: %s for func: %s, line: %lu, file: %s", aice->code, aico, tb_aico_type((tb_aico_ref_t)aico), aico->handle, tb_state_cstr(state), func_, line_, file_);
-#else
- tb_trace_e("post aice[%lu] failed, the aico[%p]: type: %lu, handle: %p, state: %s", aice->code, aico, tb_aico_type((tb_aico_ref_t)aico), aico->handle, tb_state_cstr(state));
-#endif
-
- // abort it
- tb_assert(0);
-
- // post failed
- return tb_false;
-}
-tb_bool_t tb_aicp_post_after_(tb_aicp_ref_t aicp, tb_size_t delay, tb_aice_ref_t aice __tb_debug_decl__)
-{
- // check
- tb_aicp_impl_t* impl = (tb_aicp_impl_t*)aicp;
- tb_assert_and_check_return_val(impl && impl->ptor && impl->ptor->post, tb_false);
- tb_assert_and_check_return_val(aice && aice->aico, tb_false);
-
- // killed?
- tb_check_return_val(!tb_atomic_get(&impl->kill_all), tb_false);
-
- // no delay?
- if (!delay) return tb_aicp_post_(aicp, aice __tb_debug_args__);
-
- // the aico
- tb_aico_impl_t* aico = (tb_aico_impl_t*)aice->aico;
- tb_assert_and_check_return_val(aico, tb_false);
-
- // make the posted aice
- tb_aice_ref_t posted_aice = tb_malloc0_type(tb_aice_t);
- tb_assert_and_check_return_val(posted_aice, tb_false);
-
- // init the posted aice
- *posted_aice = *aice;
-
- // run the delay task
- return tb_aico_task_run_((tb_aico_ref_t)aico, delay, tb_aicp_post_after_func, posted_aice __tb_debug_args__);
-}
-tb_void_t tb_aicp_loop(tb_aicp_ref_t aicp)
-{
- tb_aicp_loop_util(aicp, tb_null, tb_null);
-}
-tb_void_t tb_aicp_loop_util(tb_aicp_ref_t aicp, tb_bool_t (*stop)(tb_cpointer_t priv), tb_cpointer_t priv)
-{
- // check
- tb_aicp_impl_t* impl = (tb_aicp_impl_t*)aicp;
- tb_assert_and_check_return(impl);
-
- // the ptor
- tb_aicp_ptor_impl_t* ptor = impl->ptor;
- tb_assert_and_check_return(ptor && ptor->loop_spak);
-
- // the loop spak
- tb_long_t (*loop_spak)(tb_aicp_ptor_impl_t* , tb_handle_t, tb_aice_ref_t , tb_long_t ) = ptor->loop_spak;
-
- // worker++
- tb_atomic_fetch_and_inc(&impl->work);
-
- // init loop
- tb_handle_t loop = ptor->loop_init? ptor->loop_init(ptor) : tb_null;
-
- // trace
- tb_trace_d("loop[%p]: init", loop);
-
- // spak ctime
- tb_cache_time_spak();
-
- // loop
- while (1)
- {
- // spak
- tb_aice_t resp = {0};
- tb_long_t ok = loop_spak(ptor, loop, &resp, -1);
-
- // spak ctime
- tb_cache_time_spak();
-
- // failed?
- tb_check_break(ok >= 0);
-
- // timeout?
- tb_check_continue(ok);
-
- // check aico
- tb_aico_impl_t* aico = (tb_aico_impl_t*)resp.aico;
- tb_assert_and_check_continue(aico);
-
- // trace
- tb_trace_d("loop[%p]: spak: code: %lu, aico: %p, state: %s: %ld", loop, resp.code, aico, aico? tb_state_cstr(tb_atomic_get(&aico->state)) : "null", ok);
-
- // pending? clear state if be not accept or accept failed
- tb_size_t state = TB_STATE_OPENED;
- state = (resp.code != TB_AICE_CODE_ACPT || resp.state != TB_STATE_OK)? tb_atomic_fetch_and_pset(&aico->state, TB_STATE_PENDING, state) : tb_atomic_get(&aico->state);
-
- // killed or killing?
- if (state == TB_STATE_KILLED || state == TB_STATE_KILLING)
- {
- // update the aice state
- resp.state = TB_STATE_KILLED;
-
- // killing? update to the killed state
- tb_atomic_fetch_and_pset(&aico->state, TB_STATE_KILLING, TB_STATE_KILLED);
- }
-
- // done func, @note maybe the aico exit will be called
- if (resp.func && !resp.func(&resp))
- {
- // trace
-#ifdef __tb_debug__
- tb_trace_e("loop[%p]: done aice func failed with code: %lu at line: %lu, func: %s, file: %s!", loop, resp.code, aico->line, aico->func, aico->file);
-#else
- tb_trace_e("loop[%p]: done aice func failed with code: %lu!", loop, resp.code);
-#endif
- }
-
- // killing? update to the killed state
- tb_atomic_fetch_and_pset(&aico->state, TB_STATE_KILLING, TB_STATE_KILLED);
-
- // stop it?
- if (stop && stop(priv)) tb_aicp_kill(aicp);
- }
-
- // exit loop
- if (ptor->loop_exit) ptor->loop_exit(ptor, loop);
-
- // worker--
- tb_atomic_fetch_and_dec(&impl->work);
-
- // trace
- tb_trace_d("loop[%p]: exit", loop);
-}
-tb_void_t tb_aicp_kill(tb_aicp_ref_t aicp)
-{
- // check
- tb_aicp_impl_t* impl = (tb_aicp_impl_t*)aicp;
- tb_assert_and_check_return(impl);
-
- // trace
- tb_trace_d("kill: ..");
-
- // kill all
- tb_aicp_kill_all(aicp);
-
- // kill it
- if (!tb_atomic_fetch_and_set(&impl->kill, 1))
- {
- // kill proactor
- if (impl->ptor && impl->ptor->kill) impl->ptor->kill(impl->ptor);
- }
-}
-tb_void_t tb_aicp_kill_all(tb_aicp_ref_t aicp)
-{
- // check
- tb_aicp_impl_t* impl = (tb_aicp_impl_t*)aicp;
- tb_assert_and_check_return(impl);
-
- // trace
- tb_trace_d("kill: all: ..");
-
- // kill all
- if (!tb_atomic_fetch_and_set(&impl->kill_all, 1))
- {
- tb_spinlock_enter(&impl->lock);
- if (impl->pool) tb_fixed_pool_walk(impl->pool, tb_aicp_walk_kill, impl);
- tb_spinlock_leave(&impl->lock);
- }
-}
-tb_long_t tb_aicp_wait_all(tb_aicp_ref_t aicp, tb_long_t timeout)
-{
- // check
- tb_aicp_impl_t* impl = (tb_aicp_impl_t*)aicp;
- tb_assert_and_check_return_val(impl, -1);
-
- // trace
- tb_trace_d("wait: all: ..");
-
- // wait it
- tb_size_t size = 0;
- tb_hong_t time = tb_cache_time_spak();
- while ((timeout < 0 || tb_cache_time_spak() < time + timeout))
- {
- // enter
- tb_spinlock_enter(&impl->lock);
-
- // the aico count
- size = impl->pool? tb_fixed_pool_size(impl->pool) : 0;
-
- // trace
- tb_trace_d("wait: count: %lu: ..", size);
-
- // leave
- tb_spinlock_leave(&impl->lock);
-
- // ok?
- tb_check_break(size);
-
- // wait some time
- tb_msleep(200);
- }
-
- // ok?
- return !size? 1 : 0;
-}
-tb_hong_t tb_aicp_time(tb_aicp_ref_t aicp)
-{
- return tb_cache_time_mclock();
-}
diff --git a/core/src/tbox/src/tbox/asio/deprecated/aicp.h b/core/src/tbox/src/tbox/asio/deprecated/aicp.h
deleted file mode 100644
index a3e302952..000000000
--- a/core/src/tbox/src/tbox/asio/deprecated/aicp.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file aicp.h
- * @ingroup asio
- *
- */
-#ifndef TB_ASIO_AICP_H
-#define TB_ASIO_AICP_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-#include "aice.h"
-#include "../../platform/timer.h"
-#include "../../container/container.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-/// post
-#define tb_aicp_post(aicp, aice) tb_aicp_post_(aicp, aice __tb_debug_vals__)
-#define tb_aicp_post_after(aicp, delay, aice) tb_aicp_post_after_(aicp, delay, aice __tb_debug_vals__)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! the aicp instance
- *
- * @return the aicp
- */
-__tb_deprecated__
-tb_aicp_ref_t tb_aicp(tb_noarg_t);
-
-/*! init the aicp
- *
- * @param maxn the aico maxn, using the default maxn if be zero
- *
- * @return the aicp
- */
-__tb_deprecated__
-tb_aicp_ref_t tb_aicp_init(tb_size_t maxn);
-
-/*! exit the aicp
- *
- * @param aicp the aicp
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_exit(tb_aicp_ref_t aicp);
-
-/*! the aico maxn
- *
- * @param aicp the aicp
- *
- * @return the aico maxn
- */
-__tb_deprecated__
-tb_size_t tb_aicp_maxn(tb_aicp_ref_t aicp);
-
-/*! post the aice
- *
- * @param aicp the aicp
- * @param aice the aice
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_post_(tb_aicp_ref_t aicp, tb_aice_ref_t aice __tb_debug_decl__);
-
-/*! post the aice
- *
- * @param aicp the aicp
- * @param delay the delay time, ms
- * @param aice the aice
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_post_after_(tb_aicp_ref_t aicp, tb_size_t delay, tb_aice_ref_t aice __tb_debug_decl__);
-
-/*! loop aicp for the external thread
- *
- * @code
- * tb_pointer_t tb_aicp_worker_thread(tb_pointer_t)
- * {
- * tb_aicp_loop(aicp);
- * }
- * @endcode
- *
- * @param aicp the aicp
- */
-__tb_deprecated__
-tb_void_t tb_aicp_loop(tb_aicp_ref_t aicp);
-
-/*! loop aicp util ... for the external thread
- *
- * @code
- * tb_bool_t tb_aicp_stop_func(tb_pointer_t)
- * {
- * if (...) return tb_true;
- * return tb_false;
- * }
- * tb_pointer_t tb_aicp_worker_thread(tb_pointer_t)
- * {
- * tb_aicp_loop_util(aicp, stop_func, tb_null);
- * }
- * @endcode
- *
- * @param aicp the aicp
- */
-__tb_deprecated__
-tb_void_t tb_aicp_loop_util(tb_aicp_ref_t aicp, tb_bool_t (*stop)(tb_cpointer_t priv), tb_cpointer_t priv);
-
-/*! kill loop
- *
- * @param aicp the aicp
- */
-__tb_deprecated__
-tb_void_t tb_aicp_kill(tb_aicp_ref_t aicp);
-
-/*! kill all and cannot continue to post it, but not kill loop
- *
- * @param aicp the aicp
- */
-__tb_deprecated__
-tb_void_t tb_aicp_kill_all(tb_aicp_ref_t aicp);
-
-/*! wait all exiting
- *
- * @param aicp the aicp
- * @param timeout the timeout
- *
- * @return ok: > 0, timeout: 0, failed: -1
- */
-__tb_deprecated__
-tb_long_t tb_aicp_wait_all(tb_aicp_ref_t aicp, tb_long_t timeout);
-
-/*! the spak time
- *
- * @param aicp the aicp
- *
- * @return the time
- */
-__tb_deprecated__
-tb_hong_t tb_aicp_time(tb_aicp_ref_t aicp);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/asio/deprecated/aioe.h b/core/src/tbox/src/tbox/asio/deprecated/aioe.h
deleted file mode 100644
index 7bc84c34e..000000000
--- a/core/src/tbox/src/tbox/asio/deprecated/aioe.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file aioe.h
- * @ingroup asio
- *
- */
-#ifndef TB_ASIO_AIOE_H
-#define TB_ASIO_AIOE_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the aioe code enum, only for sock
-typedef enum __tb_aioe_code_e
-{
- TB_AIOE_CODE_NONE = 0x0000
-, TB_AIOE_CODE_CONN = 0x0001
-, TB_AIOE_CODE_ACPT = 0x0002
-, TB_AIOE_CODE_RECV = 0x0004
-, TB_AIOE_CODE_SEND = 0x0008
-, TB_AIOE_CODE_EALL = TB_AIOE_CODE_RECV | TB_AIOE_CODE_SEND | TB_AIOE_CODE_ACPT | TB_AIOE_CODE_CONN
-, TB_AIOE_CODE_CLEAR = 0x0010 //!< edge trigger. after the event is retrieved by the user, its state is reset
-, TB_AIOE_CODE_ONESHOT = 0x0020 //!< causes the event to return only the first occurrence of the filter being triggered
-
-}tb_aioe_code_e;
-
-/// the aioe type
-typedef struct __tb_aioe_t
-{
- /// the code
- tb_size_t code;
-
- /// the priv
- tb_cpointer_t priv;
-
- /// the aioo
- tb_aioo_ref_t aioo;
-
-}tb_aioe_t, *tb_aioe_ref_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/asio/deprecated/aioo.c b/core/src/tbox/src/tbox/asio/deprecated/aioo.c
deleted file mode 100644
index 696e20a2f..000000000
--- a/core/src/tbox/src/tbox/asio/deprecated/aioo.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file aioo.c
- * @ingroup asio
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "aioo.h"
-#include "aioe.h"
-#include "impl/prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * declaration
- */
-tb_long_t tb_aioo_rtor_wait(tb_socket_ref_t sock, tb_size_t code, tb_long_t timeout);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_socket_ref_t tb_aioo_sock(tb_aioo_ref_t aioo)
-{
- // check
- tb_aioo_impl_t const* impl = (tb_aioo_impl_t const*)aioo;
- tb_assert_and_check_return_val(impl, tb_null);
-
- // the sock
- return impl->sock;
-}
-tb_long_t tb_aioo_wait(tb_socket_ref_t sock, tb_size_t code, tb_long_t timeout)
-{
- // check
- tb_assert_and_check_return_val(sock && code, 0);
-
- // wait aioo
- return tb_aioo_rtor_wait(sock, code, timeout);
-}
-
diff --git a/core/src/tbox/src/tbox/asio/deprecated/aioo.h b/core/src/tbox/src/tbox/asio/deprecated/aioo.h
deleted file mode 100644
index f6c8bc7ed..000000000
--- a/core/src/tbox/src/tbox/asio/deprecated/aioo.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file aioo.h
- * @ingroup asio
- *
- */
-#ifndef TB_ASIO_AIOO_H
-#define TB_ASIO_AIOO_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! the aioo handle
- *
- * @param aioo the aioo
- *
- * @return the socket
- */
-__tb_deprecated__
-tb_socket_ref_t tb_aioo_sock(tb_aioo_ref_t aioo);
-
-/*! wait the aioo
- *
- * blocking wait the single event aioo, so need not aiop
- * return the event type if ok, otherwise return 0 for timeout
- *
- * @param sock the sock
- * @param code the aioe code
- * @param timeout the timeout, infinity: -1
- *
- * @return > 0: the aioe code, 0: timeout, -1: failed
- */
-__tb_deprecated__
-tb_long_t tb_aioo_wait(tb_socket_ref_t sock, tb_size_t code, tb_long_t timeout);
-
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/asio/deprecated/aiop.c b/core/src/tbox/src/tbox/asio/deprecated/aiop.c
deleted file mode 100644
index 97d38883a..000000000
--- a/core/src/tbox/src/tbox/asio/deprecated/aiop.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file aiop.c
- * @ingroup asio
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "aiop"
-#define TB_TRACE_MODULE_DEBUG (1)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "aiop.h"
-#include "aioo.h"
-#include "impl/prefix.h"
-#include "../../math/math.h"
-#include "../../utils/utils.h"
-#include "../../memory/memory.h"
-#include "../../platform/platform.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * aioo
- */
-static tb_aioo_ref_t tb_aiop_aioo_init(tb_aiop_impl_t* impl, tb_socket_ref_t sock, tb_size_t code, tb_cpointer_t priv)
-{
- // check
- tb_assert_and_check_return_val(impl && impl->pool, tb_null);
-
- // enter
- tb_spinlock_enter(&impl->lock);
-
- // make aioo
- tb_aioo_impl_t* aioo = (tb_aioo_impl_t*)tb_fixed_pool_malloc0(impl->pool);
-
- // init aioo
- if (aioo)
- {
- aioo->code = code;
- aioo->priv = priv;
- aioo->sock = sock;
- }
-
- // leave
- tb_spinlock_leave(&impl->lock);
-
- // ok?
- return (tb_aioo_ref_t)aioo;
-}
-static tb_void_t tb_aiop_aioo_exit(tb_aiop_impl_t* impl, tb_aioo_ref_t aioo)
-{
- // check
- tb_assert_and_check_return(impl && impl->pool);
-
- // enter
- tb_spinlock_enter(&impl->lock);
-
- // exit aioo
- if (aioo) tb_fixed_pool_free(impl->pool, aioo);
-
- // leave
- tb_spinlock_leave(&impl->lock);
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_aiop_ref_t tb_aiop_init(tb_size_t maxn)
-{
- // check
- tb_assert_and_check_return_val(maxn, tb_null);
-
- // done
- tb_bool_t ok = tb_false;
- tb_aiop_impl_t* impl = tb_null;
- do
- {
- // make impl
- impl = tb_malloc0_type(tb_aiop_impl_t);
- tb_assert_and_check_break(impl);
-
- // init impl
- impl->maxn = maxn;
-
- // init lock
- if (!tb_spinlock_init(&impl->lock)) break;
-
- // init pool
- impl->pool = tb_fixed_pool_init(tb_null, (maxn >> 4) + 16, sizeof(tb_aioo_impl_t), tb_null, tb_null, tb_null);
- tb_assert_and_check_break(impl->pool);
-
- // init spak
- if (!tb_socket_pair(TB_SOCKET_TYPE_TCP, impl->spak)) break;
-
- // init reactor
- impl->rtor = tb_aiop_rtor_impl_init(impl);
- tb_assert_and_check_break(impl->rtor);
-
- // addo spak
- if (!tb_aiop_addo((tb_aiop_ref_t)impl, impl->spak[1], TB_AIOE_CODE_RECV, tb_null)) break;
-
- // register lock profiler
-#ifdef TB_LOCK_PROFILER_ENABLE
- tb_lock_profiler_register(tb_lock_profiler(), (tb_pointer_t)&impl->lock, TB_TRACE_MODULE_NAME);
-#endif
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (impl) tb_aiop_exit((tb_aiop_ref_t)impl);
- impl = tb_null;
- }
-
- // ok?
- return (tb_aiop_ref_t)impl;
-}
-tb_void_t tb_aiop_exit(tb_aiop_ref_t aiop)
-{
- // check
- tb_aiop_impl_t* impl = (tb_aiop_impl_t*)aiop;
- tb_assert_and_check_return(impl);
-
- // exit reactor
- if (impl->rtor && impl->rtor->exit)
- impl->rtor->exit(impl->rtor);
-
- // exit spak
- if (impl->spak[0]) tb_socket_exit(impl->spak[0]);
- if (impl->spak[1]) tb_socket_exit(impl->spak[1]);
- impl->spak[0] = tb_null;
- impl->spak[1] = tb_null;
-
- // exit pool
- tb_spinlock_enter(&impl->lock);
- if (impl->pool) tb_fixed_pool_exit(impl->pool);
- impl->pool = tb_null;
- tb_spinlock_leave(&impl->lock);
-
- // exit lock
- tb_spinlock_exit(&impl->lock);
-
- // free impl
- tb_free(impl);
-}
-tb_void_t tb_aiop_cler(tb_aiop_ref_t aiop)
-{
- // check
- tb_aiop_impl_t* impl = (tb_aiop_impl_t*)aiop;
- tb_assert_and_check_return(impl);
-
- // clear reactor
- if (impl->rtor && impl->rtor->cler)
- impl->rtor->cler(impl->rtor);
-
- // clear pool
- tb_spinlock_enter(&impl->lock);
- if (impl->pool) tb_fixed_pool_clear(impl->pool);
- tb_spinlock_leave(&impl->lock);
-
- // addo spak
- if (impl->spak[1]) tb_aiop_addo(aiop, impl->spak[1], TB_AIOE_CODE_RECV, tb_null);
-}
-tb_bool_t tb_aiop_have(tb_aiop_ref_t aiop, tb_size_t code)
-{
- // check
- tb_aiop_impl_t* impl = (tb_aiop_impl_t*)aiop;
- tb_assert_and_check_return_val(impl && impl->rtor, tb_false);
-
- // have this code?
- return ((impl->rtor->code & code) == code)? tb_true : tb_false;
-}
-tb_void_t tb_aiop_kill(tb_aiop_ref_t aiop)
-{
- // check
- tb_aiop_impl_t* impl = (tb_aiop_impl_t*)aiop;
- tb_assert_and_check_return(impl);
-
- // kill it
- if (impl->spak[0])
- {
- // post: 'k'
- tb_long_t ok = tb_socket_send(impl->spak[0], (tb_byte_t const*)"k", 1);
- if (ok != 1)
- {
- // trace
- tb_trace_e("kill: failed!");
-
- // abort it
- tb_assert(0);
- }
- }
-}
-tb_void_t tb_aiop_spak(tb_aiop_ref_t aiop)
-{
- // check
- tb_aiop_impl_t* impl = (tb_aiop_impl_t*)aiop;
- tb_assert_and_check_return(impl);
-
- // spak it
- if (impl->spak[0])
- {
- // post: 'p'
- tb_long_t ok = tb_socket_send(impl->spak[0], (tb_byte_t const*)"p", 1);
- if (ok != 1)
- {
- // trace
- tb_trace_e("spak: failed!");
-
- // abort it
- tb_assert(0);
- }
- }
-}
-tb_aioo_ref_t tb_aiop_addo(tb_aiop_ref_t aiop, tb_socket_ref_t sock, tb_size_t code, tb_cpointer_t priv)
-{
- // check
- tb_aiop_impl_t* impl = (tb_aiop_impl_t*)aiop;
- tb_assert_and_check_return_val(impl && impl->rtor && impl->rtor->addo && sock, tb_null);
- tb_assert(tb_aiop_have(aiop, code));
-
- // done
- tb_bool_t ok = tb_false;
- tb_aioo_ref_t aioo = tb_null;
- do
- {
- // init aioo
- aioo = tb_aiop_aioo_init(impl, sock, code, priv);
- tb_assert_and_check_break(aioo);
-
- // addo aioo
- if (!impl->rtor->addo(impl->rtor, (tb_aioo_impl_t*)aioo)) break;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed? remove aioo
- if (!ok && aioo)
- {
- tb_aiop_aioo_exit(impl, aioo);
- aioo = tb_null;
- }
-
- // ok?
- return aioo;
-}
-tb_void_t tb_aiop_delo(tb_aiop_ref_t aiop, tb_aioo_ref_t aioo)
-{
- // check
- tb_aiop_impl_t* impl = (tb_aiop_impl_t*)aiop;
- tb_assert_and_check_return(impl && impl->rtor && impl->rtor->delo && aioo);
-
- // delete aioo from aiop
- if (!impl->rtor->delo(impl->rtor, (tb_aioo_impl_t*)aioo))
- {
- // trace
- tb_trace_e("delo: aioo[%p] failed!", aioo);
- }
-
- // exit aioo
- tb_aiop_aioo_exit(impl, aioo);
-}
-tb_bool_t tb_aiop_post(tb_aiop_ref_t aiop, tb_aioe_ref_t aioe)
-{
- // check
- tb_aiop_impl_t* impl = (tb_aiop_impl_t*)aiop;
- tb_assert_and_check_return_val(impl && impl->rtor && impl->rtor->post && aioe, tb_false);
- tb_assert(tb_aiop_have(aiop, aioe->code));
-
- // post
- return impl->rtor->post(impl->rtor, aioe);
-}
-tb_bool_t tb_aiop_sete(tb_aiop_ref_t aiop, tb_aioo_ref_t aioo, tb_size_t code, tb_cpointer_t priv)
-{
- // check
- tb_aiop_impl_t* impl = (tb_aiop_impl_t*)aiop;
- tb_assert_and_check_return_val(impl && aioo && tb_aioo_sock(aioo) && code, tb_false);
-
- // init aioe
- tb_aioe_t aioe;
- aioe.code = code;
- aioe.priv = priv;
- aioe.aioo = aioo;
-
- // post aioe
- return tb_aiop_post(aiop, &aioe);
-}
-tb_long_t tb_aiop_wait(tb_aiop_ref_t aiop, tb_aioe_ref_t list, tb_size_t maxn, tb_long_t timeout)
-{
- // check
- tb_aiop_impl_t* impl = (tb_aiop_impl_t*)aiop;
- tb_assert_and_check_return_val(impl && impl->rtor && impl->rtor->wait && list, -1);
-
- // wait
- return impl->rtor->wait(impl->rtor, list, maxn, timeout);
-}
-
diff --git a/core/src/tbox/src/tbox/asio/deprecated/aiop.h b/core/src/tbox/src/tbox/asio/deprecated/aiop.h
deleted file mode 100644
index 5a9181f59..000000000
--- a/core/src/tbox/src/tbox/asio/deprecated/aiop.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file aiop.h
- * @ingroup asio
- *
- */
-#ifndef TB_ASIO_AIOP_H
-#define TB_ASIO_AIOP_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-#include "aioo.h"
-#include "aioe.h"
-#include "../../platform/prefix.h"
-#include "../../container/container.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init the aiop
- *
- * @param maxn the maximum number of concurrent objects
- *
- * @return the aiop
- */
-__tb_deprecated__
-tb_aiop_ref_t tb_aiop_init(tb_size_t maxn);
-
-/*! exit the aiop
- *
- * @param aiop the aiop
- */
-__tb_deprecated__
-tb_void_t tb_aiop_exit(tb_aiop_ref_t aiop);
-
-/*! cler the aiop
- *
- * @param aiop the aiop
- */
-__tb_deprecated__
-tb_void_t tb_aiop_cler(tb_aiop_ref_t aiop);
-
-/*! kill the aiop
- *
- * @param aiop the aiop
- */
-__tb_deprecated__
-tb_void_t tb_aiop_kill(tb_aiop_ref_t aiop);
-
-/*! spak the aiop, break the wait
- *
- * @param aiop the aiop
- */
-__tb_deprecated__
-tb_void_t tb_aiop_spak(tb_aiop_ref_t aiop);
-
-/*! the aioe code is supported for the aiop?
- *
- * @param aiop the aiop
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aiop_have(tb_aiop_ref_t aiop, tb_size_t code);
-
-/*! addo the aioo
- *
- * @param aiop the aiop
- * @param sock the socket
- * @param code the code
- * @param priv the private data
- *
- * @return the aioo
- */
-__tb_deprecated__
-tb_aioo_ref_t tb_aiop_addo(tb_aiop_ref_t aiop, tb_socket_ref_t sock, tb_size_t code, tb_cpointer_t priv);
-
-/*! delo the aioo
- *
- * @param aiop the aiop
- * @param aioo the aioo
- *
- */
-__tb_deprecated__
-tb_void_t tb_aiop_delo(tb_aiop_ref_t aiop, tb_aioo_ref_t aioo);
-
-/*! post the aioe
- *
- * @param aiop the aiop
- * @param aioe the aioe
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aiop_post(tb_aiop_ref_t aiop, tb_aioe_ref_t aioe);
-
-/*! set the aioe
- *
- * @param aiop the aiop
- * @param aioo the aioo
- * @param code the code
- * @param priv the private data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aiop_sete(tb_aiop_ref_t aiop, tb_aioo_ref_t aioo, tb_size_t code, tb_cpointer_t priv);
-
-/*! wait the asio objects in the pool
- *
- * blocking wait the multiple event objects
- * return the event number if ok, otherwise return 0 for timeout
- *
- * @param aiop the aiop
- * @param list the aioe list
- * @param maxn the aioe maxn
- * @param timeout the timeout, infinity: -1
- *
- * @return > 0: the aioe list size, 0: timeout, -1: failed
- */
-__tb_deprecated__
-tb_long_t tb_aiop_wait(tb_aiop_ref_t aiop, tb_aioe_ref_t list, tb_size_t maxn, tb_long_t timeout);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/asio/deprecated/asio.h b/core/src/tbox/src/tbox/asio/deprecated/asio.h
deleted file mode 100644
index a8b872fb0..000000000
--- a/core/src/tbox/src/tbox/asio/deprecated/asio.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file asio.h
- * @defgroup asio
- *
- */
-#ifndef TB_ASIO_DEPRECATED_H
-#define TB_ASIO_DEPRECATED_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-#include "aioo.h"
-#include "aioe.h"
-#include "aiop.h"
-#include "aico.h"
-#include "aice.h"
-#include "aicp.h"
-#include "http.h"
-#include "dns.h"
-#include "ssl.h"
-
-
-#endif
diff --git a/core/src/tbox/src/tbox/asio/deprecated/deprecated.h b/core/src/tbox/src/tbox/asio/deprecated/deprecated.h
deleted file mode 100644
index 429191ba8..000000000
--- a/core/src/tbox/src/tbox/asio/deprecated/deprecated.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file deprecated.h
- * @defgroup asio
- *
- */
-#ifndef TB_ASIO_DEPRECATED_H
-#define TB_ASIO_DEPRECATED_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "asio.h"
-
-
-#endif
diff --git a/core/src/tbox/src/tbox/asio/deprecated/dns.c b/core/src/tbox/src/tbox/asio/deprecated/dns.c
deleted file mode 100644
index 3af9ca589..000000000
--- a/core/src/tbox/src/tbox/asio/deprecated/dns.c
+++ /dev/null
@@ -1,571 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file dns.c
- * @ingroup asio
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "aicp_dns"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "dns.h"
-#include "aico.h"
-#include "aicp.h"
-#include "../../network/network.h"
-#include "../../platform/platform.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the aicp impl done type
-typedef struct __tb_aicp_dns_done_t
-{
- // the func
- tb_aicp_dns_done_func_t func;
-
- // the priv
- tb_cpointer_t priv;
-
-}tb_aicp_dns_done_t;
-
-// the aicp impl type
-typedef struct __tb_aicp_dns_impl_t
-{
- // the done
- tb_aicp_dns_done_t done;
-
- // the aicp
- tb_aicp_ref_t aicp;
-
- // the aico
- tb_aico_ref_t aico;
-
- // the server indx
- tb_size_t indx;
-
- // the server list
- tb_ipaddr_t list[3];
-
- // the server size
- tb_size_t size;
-
- // the data
- tb_byte_t data[TB_DNS_RPKT_MAXN];
-
- // the host
- tb_char_t host[256];
-
-}tb_aicp_dns_impl_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * private implementation
- */
-static tb_size_t tb_aicp_dns_reqt_init(tb_aicp_dns_impl_t* impl)
-{
- // check
- tb_assert_and_check_return_val(impl, 0);
-
- // init query data
- tb_static_stream_t stream;
- tb_static_stream_init(&stream, impl->data, TB_DNS_RPKT_MAXN);
-
- // identification number
- tb_static_stream_writ_u16_be(&stream, TB_DNS_HEADER_MAGIC);
-
- /* 0x2104: 0 0000 001 0000 0000
- *
- * tb_uint16_t qr :1; // query/response flag
- * tb_uint16_t opcode :4; // purpose of message
- * tb_uint16_t aa :1; // authoritive answer
- * tb_uint16_t tc :1; // truncated message
- * tb_uint16_t rd :1; // recursion desired
-
- * tb_uint16_t ra :1; // recursion available
- * tb_uint16_t z :1; // its z! reserved
- * tb_uint16_t ad :1; // authenticated data
- * tb_uint16_t cd :1; // checking disabled
- * tb_uint16_t rcode :4; // response code
- *
- * this is a query
- * this is a standard query
- * not authoritive answer
- * not truncated
- * recursion desired
- *
- * recursion not available! hey we dont have it (lol)
- *
- */
-#if 1
- tb_static_stream_writ_u16_be(&stream, 0x0100);
-#else
- tb_static_stream_writ_u1(&stream, 0); // this is a query
- tb_static_stream_writ_ubits32(&stream, 0, 4); // this is a standard query
- tb_static_stream_writ_u1(&stream, 0); // not authoritive answer
- tb_static_stream_writ_u1(&stream, 0); // not truncated
- tb_static_stream_writ_u1(&stream, 1); // recursion desired
-
- tb_static_stream_writ_u1(&stream, 0); // recursion not available! hey we dont have it (lol)
- tb_static_stream_writ_u1(&stream, 0);
- tb_static_stream_writ_u1(&stream, 0);
- tb_static_stream_writ_u1(&stream, 0);
- tb_static_stream_writ_ubits32(&stream, 0, 4);
-#endif
-
- /* we have only one question
- *
- * tb_uint16_t question; // number of question entries
- * tb_uint16_t answer; // number of answer entries
- * tb_uint16_t authority; // number of authority entries
- * tb_uint16_t resource; // number of resource entries
- *
- */
- tb_static_stream_writ_u16_be(&stream, 1);
- tb_static_stream_writ_u16_be(&stream, 0);
- tb_static_stream_writ_u16_be(&stream, 0);
- tb_static_stream_writ_u16_be(&stream, 0);
-
- // set questions, see as tb_dns_question_t
- // name + question1 + question2 + ...
- tb_static_stream_writ_u8(&stream, '.');
- tb_char_t* p = tb_static_stream_writ_cstr(&stream, impl->host);
-
- // only one question now.
- tb_static_stream_writ_u16_be(&stream, 1); // we are requesting the ipv4 dnsess
- tb_static_stream_writ_u16_be(&stream, 1); // it's internet (lol)
-
- // encode impl name
- if (!p || !tb_dns_encode_name(p - 1)) return 0;
-
- // ok?
- return tb_static_stream_offset(&stream);
-}
-static tb_bool_t tb_aicp_dns_resp_done(tb_aicp_dns_impl_t* impl, tb_size_t size, tb_ipaddr_ref_t addr)
-{
- // check
- tb_assert_and_check_return_val(impl && addr, tb_false);
-
- // check
- tb_assert_and_check_return_val(size >= TB_DNS_HEADER_SIZE, tb_false);
-
- // init stream
- tb_static_stream_t stream;
- tb_static_stream_init(&stream, impl->data, size);
-
- // init header
- tb_dns_header_t header;
- header.id = tb_static_stream_read_u16_be(&stream); tb_static_stream_skip(&stream, 2);
- header.question = tb_static_stream_read_u16_be(&stream);
- header.answer = tb_static_stream_read_u16_be(&stream);
- header.authority = tb_static_stream_read_u16_be(&stream);
- header.resource = tb_static_stream_read_u16_be(&stream);
-
- // trace
- tb_trace_d("response: size: %u", size);
- tb_trace_d("response: id: 0x%04x", header.id);
- tb_trace_d("response: question: %d", header.question);
- tb_trace_d("response: answer: %d", header.answer);
- tb_trace_d("response: authority: %d", header.authority);
- tb_trace_d("response: resource: %d", header.resource);
- tb_trace_d("");
-
- // check header
- tb_assert_and_check_return_val(header.id == TB_DNS_HEADER_MAGIC, tb_false);
-
- // skip questions, only one question now.
- // name + question1 + question2 + ...
- tb_assert_and_check_return_val(header.question == 1, tb_false);
-#if 1
- tb_static_stream_skip_cstr(&stream);
- tb_static_stream_skip(&stream, 4);
-#else
- tb_char_t* name = tb_static_stream_read_cstr(&stream);
- //name = tb_dns_decode_name(name);
- tb_assert_and_check_return_val(name, tb_false);
- tb_static_stream_skip(&stream, 4);
- tb_trace_d("response: name: %s", name);
-#endif
-
- // decode answers
- tb_size_t i = 0;
- tb_size_t found = 0;
- for (i = 0; i < header.answer; i++)
- {
- // decode answer
- tb_dns_answer_t answer;
-
- // trace
- tb_trace_d("response: answer: %d", i);
-
- // decode impl name
- tb_char_t const* name = tb_dns_decode_name(&stream, answer.name); tb_used(name);
-
- // trace
- tb_trace_d("response: name: %s", name);
-
- // decode resource
- answer.res.type = tb_static_stream_read_u16_be(&stream);
- answer.res.class_ = tb_static_stream_read_u16_be(&stream);
- answer.res.ttl = tb_static_stream_read_u32_be(&stream);
- answer.res.size = tb_static_stream_read_u16_be(&stream);
-
- // trace
- tb_trace_d("response: type: %d", answer.res.type);
- tb_trace_d("response: class: %d", answer.res.class_);
- tb_trace_d("response: ttl: %d", answer.res.ttl);
- tb_trace_d("response: size: %d", answer.res.size);
-
- // is ipv4?
- if (answer.res.type == 1)
- {
- // get ipv4
- tb_byte_t b1 = tb_static_stream_read_u8(&stream);
- tb_byte_t b2 = tb_static_stream_read_u8(&stream);
- tb_byte_t b3 = tb_static_stream_read_u8(&stream);
- tb_byte_t b4 = tb_static_stream_read_u8(&stream);
-
- // trace
- tb_trace_d("response: ipv4: %u.%u.%u.%u", b1, b2, b3, b4);
-
- // save the first ip
- if (!found)
- {
- // save it
- if (addr)
- {
- // init ipv4
- tb_ipv4_t ipv4;
- ipv4.u8[0] = b1;
- ipv4.u8[1] = b2;
- ipv4.u8[2] = b3;
- ipv4.u8[3] = b4;
-
- // save ipv4
- tb_ipaddr_ipv4_set(addr, &ipv4);
- }
-
- // found it
- found = 1;
-
- // trace
- tb_trace_d("response: ");
- break;
- }
- }
- else
- {
- // decode rdata
- answer.rdata = (tb_byte_t const*)tb_dns_decode_name(&stream, answer.name);
-
- // trace
- tb_trace_d("response: alias: %s", answer.rdata? (tb_char_t const*)answer.rdata : "");
- }
-
- // trace
- tb_trace_d("response: ");
- }
-
- // found it?
- tb_check_return_val(found, tb_false);
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_aicp_dns_reqt_func(tb_aice_ref_t aice);
-static tb_bool_t tb_aicp_dns_resp_func(tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(aice && aice->aico && aice->code == TB_AICE_CODE_URECV, tb_false);
-
- // the aicp
- tb_aicp_ref_t aicp = (tb_aicp_ref_t)tb_aico_aicp(aice->aico);
- tb_assert_and_check_return_val(aicp, tb_false);
-
- // the impl
- tb_aicp_dns_impl_t* impl = (tb_aicp_dns_impl_t*)aice->priv;
- tb_assert_and_check_return_val(impl, tb_false);
-
- // done
- tb_ipaddr_t addr = {0};
- if (aice->state == TB_STATE_OK)
- {
- // trace
- tb_trace_d("resp[%s]: aico: %p, server: %{ipaddr}, real: %lu", impl->host, impl->aico, &aice->u.urecv.addr, aice->u.urecv.real);
-
- // check
- tb_assert_and_check_return_val(aice->u.urecv.real, tb_false);
-
- // done resp
- tb_aicp_dns_resp_done(impl, aice->u.urecv.real, &addr);
- }
- // timeout or failed?
- else
- {
- // trace
- tb_trace_d("resp[%s]: aico: %p, state: %s", impl->host, impl->aico, tb_state_cstr(aice->state));
- }
-
- // ok or try to get ok from cache again if failed or timeout?
- tb_bool_t from_cache = tb_false;
- if (!tb_ipaddr_ip_is_empty(&addr) || (from_cache = tb_dns_cache_get(impl->host, &addr)))
- {
- // save to cache
- if (!from_cache) tb_dns_cache_set(impl->host, &addr);
-
- // done func
- impl->done.func((tb_aicp_dns_ref_t)impl, impl->host, &addr, impl->done.priv);
- return tb_true;
- }
-
- // try next server?
- tb_bool_t ok = tb_false;
- tb_ipaddr_ref_t server = &impl->list[impl->indx + 1];
- if (!tb_ipaddr_is_empty(server))
- {
- // indx++
- impl->indx++;
-
- // init reqt
- tb_size_t size = tb_aicp_dns_reqt_init(impl);
- if (size)
- {
- // post reqt
- ok = tb_aico_usend(aice->aico, server, impl->data, size, tb_aicp_dns_reqt_func, (tb_pointer_t)impl);
- }
- }
-
- // failed? done func
- if (!ok) impl->done.func((tb_aicp_dns_ref_t)impl, impl->host, tb_null, impl->done.priv);
-
- // continue
- return tb_true;
-}
-static tb_bool_t tb_aicp_dns_reqt_func(tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(aice && aice->aico && aice->code == TB_AICE_CODE_USEND, tb_false);
-
- // the aicp
- tb_aicp_ref_t aicp = (tb_aicp_ref_t)tb_aico_aicp(aice->aico);
- tb_assert_and_check_return_val(aicp, tb_false);
-
- // the impl
- tb_aicp_dns_impl_t* impl = (tb_aicp_dns_impl_t*)aice->priv;
- tb_assert_and_check_return_val(impl && impl->done.func, tb_false);
-
- // done
- tb_bool_t ok = tb_false;
- if (aice->state == TB_STATE_OK)
- {
- // trace
- tb_trace_d("reqt[%s]: aico: %p, server: %{ipaddr}, real: %lu", impl->host, impl->aico, &aice->u.usend.addr, aice->u.usend.real);
-
- // check
- tb_assert_and_check_return_val(aice->u.usend.real, tb_false);
-
- // post resp
- ok = tb_aico_urecv(aice->aico, impl->data, sizeof(impl->data), tb_aicp_dns_resp_func, (tb_pointer_t)impl);
- }
- // timeout or failed?
- else
- {
- // trace
- tb_trace_d("reqt[%s]: aico: %p, server: %{ipaddr}, state: %s", impl->host, impl->aico, &aice->u.usend.addr, tb_state_cstr(aice->state));
-
- // the next server
- tb_ipaddr_ref_t server = &impl->list[impl->indx + 1];
- if (!tb_ipaddr_is_empty(server))
- {
- // indx++
- impl->indx++;
-
- // init reqt
- tb_size_t size = tb_aicp_dns_reqt_init(impl);
- if (size)
- {
- // post reqt
- ok = tb_aico_usend(aice->aico, server, impl->data, size, tb_aicp_dns_reqt_func, (tb_pointer_t)impl);
- }
- }
- }
-
- // failed? done func
- if (!ok) impl->done.func((tb_aicp_dns_ref_t)impl, impl->host, tb_null, impl->done.priv);
-
- // continue
- return tb_true;
-}
-static tb_bool_t tb_aicp_dns_clos_func(tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(aice && aice->aico && aice->code == TB_AICE_CODE_CLOS, tb_false);
-
- // trace
- tb_trace_d("exit: aico: %p: ok", aice->aico);
-
- // exit aico
- tb_aico_exit(aice->aico);
-
- // ok
- return tb_true;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_aicp_dns_ref_t tb_aicp_dns_init(tb_aicp_ref_t aicp)
-{
- // check
- tb_assert_and_check_return_val(aicp, tb_null);
-
- // done
- tb_bool_t ok = tb_false;
- tb_aicp_dns_impl_t* impl = tb_null;
- do
- {
- // make impl
- impl = tb_malloc0_type(tb_aicp_dns_impl_t);
- tb_assert_and_check_break(impl);
-
- // init aicp
- impl->aicp = aicp;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (impl) tb_aicp_dns_exit((tb_aicp_dns_ref_t)impl);
- impl = tb_null;
- }
-
- // ok?
- return (tb_aicp_dns_ref_t)impl;
-}
-tb_void_t tb_aicp_dns_kill(tb_aicp_dns_ref_t dns)
-{
- // check
- tb_aicp_dns_impl_t* impl = (tb_aicp_dns_impl_t*)dns;
- tb_assert_and_check_return(impl);
-
- // trace
- tb_trace_d("kill: aico: %p ..", impl->aico);
-
- // kill it
- if (impl->aico) tb_aico_kill(impl->aico);
-}
-tb_void_t tb_aicp_dns_exit(tb_aicp_dns_ref_t dns)
-{
- // check
- tb_aicp_dns_impl_t* impl = (tb_aicp_dns_impl_t*)dns;
- tb_assert_and_check_return(impl);
-
- // trace
- tb_trace_d("exit: aico: %p ..", impl->aico);
-
- // clos aico
- if (impl->aico) tb_aico_clos(impl->aico, tb_aicp_dns_clos_func, tb_null);
- impl->aico = tb_null;
-
- // exit it
- tb_free(impl);
-}
-tb_bool_t tb_aicp_dns_done(tb_aicp_dns_ref_t dns, tb_char_t const* host, tb_long_t timeout, tb_aicp_dns_done_func_t func, tb_cpointer_t priv)
-{
- // check
- tb_aicp_dns_impl_t* impl = (tb_aicp_dns_impl_t*)dns;
- tb_assert_and_check_return_val(impl && func && host && host[0], tb_false);
-
- // trace
- tb_trace_d("done: aico: %p, host: %s: ..", impl->aico, host);
-
- // init func
- impl->done.func = func;
- impl->done.priv = priv;
-
- // save host
- tb_strlcpy(impl->host, host, sizeof(impl->host));
-
- // only address? ok
- tb_ipaddr_t addr = {0};
- if (tb_ipaddr_ip_cstr_set(&addr, impl->host, TB_IPADDR_FAMILY_NONE))
- {
- impl->done.func(dns, impl->host, &addr, impl->done.priv);
- return tb_true;
- }
-
- // try to lookup it from cache first
- if (tb_dns_cache_get(impl->host, &addr))
- {
- impl->done.func(dns, impl->host, &addr, impl->done.priv);
- return tb_true;
- }
-
- // init server list
- if (!impl->size) impl->size = tb_dns_server_get(impl->list);
- tb_check_return_val(impl->size, tb_false);
-
- // get the server
- tb_ipaddr_ref_t server = &impl->list[impl->indx = 0];
- tb_assert_and_check_return_val(!tb_ipaddr_is_empty(server), tb_false);
-
- // init reqt
- tb_size_t size = tb_aicp_dns_reqt_init(impl);
- tb_assert_and_check_return_val(size, tb_false);
-
- // init it first if no aico
- if (!impl->aico)
- {
- // init aico
- impl->aico = tb_aico_init(impl->aicp);
- tb_assert_and_check_return_val(impl->aico, tb_false);
-
- // open aico
- if (!tb_aico_open_sock_from_type(impl->aico, TB_SOCKET_TYPE_UDP, tb_ipaddr_family(server))) return tb_false;
-
- // init timeout
- tb_aico_timeout_set(impl->aico, TB_AICO_TIMEOUT_SEND, timeout);
- tb_aico_timeout_set(impl->aico, TB_AICO_TIMEOUT_RECV, timeout);
- }
-
- // post reqt
- return tb_aico_usend(impl->aico, server, impl->data, size, tb_aicp_dns_reqt_func, (tb_pointer_t)impl);
-}
-tb_aicp_ref_t tb_aicp_dns_aicp(tb_aicp_dns_ref_t dns)
-{
- // check
- tb_aicp_dns_impl_t* impl = (tb_aicp_dns_impl_t*)dns;
- tb_assert_and_check_return_val(impl && impl->aico, tb_null);
-
- // the aicp
- return impl->aicp;
-}
diff --git a/core/src/tbox/src/tbox/asio/deprecated/dns.h b/core/src/tbox/src/tbox/asio/deprecated/dns.h
deleted file mode 100644
index 8b5ca3662..000000000
--- a/core/src/tbox/src/tbox/asio/deprecated/dns.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file dns.h
- * @ingroup asio
- *
- */
-#ifndef TB_ASIO_DNS_H
-#define TB_ASIO_DNS_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "aicp.h"
-#include "../../network/ipaddr.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the aicp dns ref type
-typedef __tb_typeref__(aicp_dns);
-
-/// the aicp dns done func type
-typedef tb_void_t (*tb_aicp_dns_done_func_t)(tb_aicp_dns_ref_t dns, tb_char_t const* host, tb_ipaddr_ref_t addr, tb_cpointer_t priv);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init the dns
- *
- * @param aicp the aicp
- *
- * @return the dns
- */
-__tb_deprecated__
-tb_aicp_dns_ref_t tb_aicp_dns_init(tb_aicp_ref_t aicp);
-
-/*! kill the dns
- *
- * @param dns the dns
- */
-__tb_deprecated__
-tb_void_t tb_aicp_dns_kill(tb_aicp_dns_ref_t dns);
-
-/*! exit the dns
- *
- * @param dns the dns
- */
-__tb_deprecated__
-tb_void_t tb_aicp_dns_exit(tb_aicp_dns_ref_t dns);
-
-/*! done the dns
- *
- * @param dns the dns
- * @param host the host
- * @param timeout the timeout, ms
- * @param func the done func
- * @param priv the func private data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_dns_done(tb_aicp_dns_ref_t dns, tb_char_t const* host, tb_long_t timeout, tb_aicp_dns_done_func_t func, tb_cpointer_t priv);
-
-/*! the dns aicp
- *
- * @param handle the dns handle
- *
- * @return the aicp
- */
-__tb_deprecated__
-tb_aicp_ref_t tb_aicp_dns_aicp(tb_aicp_dns_ref_t dns);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/asio/deprecated/http.c b/core/src/tbox/src/tbox/asio/deprecated/http.c
deleted file mode 100644
index cab80df34..000000000
--- a/core/src/tbox/src/tbox/asio/deprecated/http.c
+++ /dev/null
@@ -1,1770 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file http.c
- * @ingroup asio
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "aicp_http"
-#define TB_TRACE_MODULE_DEBUG (1)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "http.h"
-#include "aico.h"
-#include "aicp.h"
-#include "../../zip/zip.h"
-#include "../../string/string.h"
-#include "../../stream/stream.h"
-#include "../../network/network.h"
-#include "../../platform/platform.h"
-#include "../../algorithm/algorithm.h"
-#include "../../container/container.h"
-#include "../../network/impl/http/date.h"
-#include "../../network/impl/http/option.h"
-#include "../../network/impl/http/status.h"
-#include "../../network/impl/http/method.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the aicp http impl open and read type
-typedef struct __tb_aicp_http_open_read_t
-{
- // the func
- tb_aicp_http_read_func_t func;
-
- // the priv
- tb_cpointer_t priv;
-
- // the size
- tb_size_t size;
-
-}tb_aicp_http_open_read_t;
-
-// the aicp http impl open and seek type
-typedef struct __tb_aicp_http_open_seek_t
-{
- // the func
- tb_aicp_http_seek_func_t func;
-
- // the priv
- tb_cpointer_t priv;
-
- // the offset
- tb_hize_t offset;
-
-}tb_aicp_http_open_seek_t;
-
-// the aicp http impl close opening type
-typedef struct __tb_aicp_http_clos_opening_t
-{
- // the func
- tb_aicp_http_open_func_t func;
-
- // the priv
- tb_cpointer_t priv;
-
- // the state
- tb_size_t state;
-
-}tb_aicp_http_clos_opening_t;
-
-// the aicp http impl type
-typedef struct __tb_aicp_http_impl_t
-{
- // the option
- tb_http_option_t option;
-
- // the status
- tb_http_status_t status;
-
- // the stream
- tb_async_stream_ref_t stream;
-
- // the sstream for sock
- tb_async_stream_ref_t sstream;
-
- // the cstream for chunked
- tb_async_stream_ref_t cstream;
-
- // the zstream for gzip/deflate
- tb_async_stream_ref_t zstream;
-
- // the request head
- tb_hash_map_ref_t head;
-
- // the cookies
- tb_string_t cookies;
-
- // the transfer for post
- tb_async_transfer_ref_t transfer;
-
- /* the state
- *
- * TB_STATE_CLOSED
- * TB_STATE_OPENED
- * TB_STATE_OPENING
- * TB_STATE_KILLING
- */
- tb_atomic_t state;
-
- // the line data
- tb_string_t line_data;
-
- // the line size
- tb_size_t line_size;
-
- // the cache data
- tb_buffer_t cache_data;
-
- // the cache read
- tb_size_t cache_read;
-
- // the redirect tryn
- tb_size_t redirect_tryn;
-
- // the content read
- tb_hize_t content_read;
-
- // the clos opening
- tb_aicp_http_clos_opening_t clos_opening;
-
- // the open and read, writ, seek, ...
- union
- {
- tb_aicp_http_open_read_t read;
- tb_aicp_http_open_seek_t seek;
-
- } open_and;
-
- // the func
- union
- {
- tb_aicp_http_open_func_t open;
- tb_aicp_http_read_func_t read;
- tb_aicp_http_seek_func_t seek;
- tb_aicp_http_task_func_t task;
- tb_aicp_http_clos_func_t clos;
-
- } func;
-
- // the priv
- tb_cpointer_t priv;
-
-}tb_aicp_http_impl_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * declaration
- */
-static tb_bool_t tb_aicp_http_open_done(tb_aicp_http_impl_t* impl);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static tb_char_t const* tb_aicp_http_head_format(tb_aicp_http_impl_t* impl, tb_hize_t post_size, tb_size_t* head_size, tb_size_t* state)
-{
- // check
- tb_assert_and_check_return_val(impl && head_size, tb_null);
-
- // clear line data
- tb_string_clear(&impl->line_data);
-
- // init the head value
- tb_char_t data[8192];
- tb_static_string_t value;
- if (!tb_static_string_init(&value, data, sizeof(data))) return tb_null;
-
- // init method
- tb_char_t const* method = tb_http_method_cstr(impl->option.method);
- tb_assert_and_check_return_val(method, tb_null);
-
- // init path
- tb_char_t const* path = tb_url_path(&impl->option.url);
- tb_assert_and_check_return_val(path, tb_null);
-
- // init args
- tb_char_t const* args = tb_url_args(&impl->option.url);
-
- // init host
- tb_char_t const* host = tb_url_host(&impl->option.url);
- tb_assert_and_check_return_val(host, tb_null);
- tb_hash_map_insert(impl->head, "Host", host);
-
- // init accept
- tb_hash_map_insert(impl->head, "Accept", "*/*");
-
- // init connection
- tb_hash_map_insert(impl->head, "Connection", impl->status.balived? "keep-alive" : "close");
-
- // init cookies
- tb_bool_t cookie = tb_false;
- if (impl->option.cookies)
- {
- // update cookie
- if (tb_cookies_get(impl->option.cookies, host, path, tb_url_ssl(&impl->option.url), &impl->cookies))
- {
- tb_hash_map_insert(impl->head, "Cookie", tb_string_cstr(&impl->cookies));
- cookie = tb_true;
- }
- }
-
- // no cookie? remove it
- if (!cookie) tb_hash_map_remove(impl->head, "Cookie");
-
- // init range
- if (impl->option.range.bof && impl->option.range.eof >= impl->option.range.bof)
- tb_static_string_cstrfcpy(&value, "bytes=%llu-%llu", impl->option.range.bof, impl->option.range.eof);
- else if (impl->option.range.bof && !impl->option.range.eof)
- tb_static_string_cstrfcpy(&value, "bytes=%llu-", impl->option.range.bof);
- else if (!impl->option.range.bof && impl->option.range.eof)
- tb_static_string_cstrfcpy(&value, "bytes=0-%llu", impl->option.range.eof);
- else if (impl->option.range.bof > impl->option.range.eof)
- {
- // save state
- if (state) *state = TB_STATE_HTTP_RANGE_INVALID;
- return tb_null;
- }
-
- // update range
- if (tb_static_string_size(&value)) tb_hash_map_insert(impl->head, "Range", tb_static_string_cstr(&value));
- // remove range
- else tb_hash_map_remove(impl->head, "Range");
-
- // init post
- if (impl->option.method == TB_HTTP_METHOD_POST)
- {
- // append post size
- tb_static_string_cstrfcpy(&value, "%llu", post_size);
- tb_hash_map_insert(impl->head, "Content-Length", tb_static_string_cstr(&value));
- }
- // remove post
- else tb_hash_map_remove(impl->head, "Content-Length");
-
- // replace the custom head
- tb_char_t const* head_data = (tb_char_t const*)tb_buffer_data(&impl->option.head_data);
- tb_char_t const* head_tail = head_data + tb_buffer_size(&impl->option.head_data);
- while (head_data < head_tail)
- {
- // the name and data
- tb_char_t const* name = head_data;
- tb_char_t const* data = head_data + tb_strlen(name) + 1;
- tb_check_break(data < head_tail);
-
- // replace it
- tb_hash_map_insert(impl->head, name, data);
-
- // next
- head_data = data + tb_strlen(data) + 1;
- }
-
- // exit the head value
- tb_static_string_exit(&value);
-
- // check head
- tb_assert_and_check_return_val(tb_hash_map_size(impl->head), tb_null);
-
- // append method
- tb_string_cstrcat(&impl->line_data, method);
-
- // append ' '
- tb_string_chrcat(&impl->line_data, ' ');
-
- // encode path
- tb_url_encode2(path, tb_strlen(path), data, sizeof(data) - 1);
- path = data;
-
- // append path
- tb_string_cstrcat(&impl->line_data, path);
-
- // append args if exists
- if (args)
- {
- // append '?'
- tb_string_chrcat(&impl->line_data, '?');
-
- // encode args
- tb_url_encode2(args, tb_strlen(args), data, sizeof(data) - 1);
- args = data;
-
- // append args
- tb_string_cstrcat(&impl->line_data, args);
- }
-
- // append ' '
- tb_string_chrcat(&impl->line_data, ' ');
-
- // append version, HTTP/1.1
- tb_string_cstrfcat(&impl->line_data, "HTTP/1.%1u\r\n", impl->option.version);
-
- // append key: value
- tb_for_all (tb_hash_map_item_ref_t, item, impl->head)
- {
- if (item && item->name && item->data)
- tb_string_cstrfcat(&impl->line_data, "%s: %s\r\n", (tb_char_t const*)item->name, (tb_char_t const*)item->data);
- }
-
- // append end
- tb_string_cstrcat(&impl->line_data, "\r\n");
-
- // save the head size
- *head_size = tb_string_size(&impl->line_data);
-
- // ok
- return tb_string_cstr(&impl->line_data);
-}
-static tb_bool_t tb_aicp_http_open_read_func(tb_aicp_http_ref_t http, tb_size_t state, tb_http_status_t const* status, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_open_read_t* open_read = (tb_aicp_http_open_read_t*)priv;
- tb_assert_and_check_return_val(http && status && open_read && open_read->func, tb_false);
-
- // done
- tb_bool_t ok = tb_true;
- do
- {
- // ok?
- tb_check_break(state == TB_STATE_OK);
-
- // reset state
- state = TB_STATE_UNKNOWN_ERROR;
-
- // read it
- if (!tb_aicp_http_read(http, open_read->size, open_read->func, open_read->priv)) break;
-
- // ok
- state = TB_STATE_OK;
-
- } while (0);
-
- // failed?
- if (state != TB_STATE_OK)
- {
- // done func
- ok = open_read->func(http, state, tb_null, 0, open_read->size, open_read->priv);
- }
-
- // ok?
- return ok;
-}
-static tb_bool_t tb_aicp_http_open_seek_func(tb_aicp_http_ref_t http, tb_size_t state, tb_http_status_t const* status, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_open_seek_t* open_seek = (tb_aicp_http_open_seek_t*)priv;
- tb_assert_and_check_return_val(http && status && open_seek && open_seek->func, tb_false);
-
- // done
- tb_bool_t ok = tb_true;
- do
- {
- // ok?
- tb_check_break(state == TB_STATE_OK);
-
- // reset state
- state = TB_STATE_UNKNOWN_ERROR;
-
- // seek it
- if (!tb_aicp_http_seek(http, open_seek->offset, open_seek->func, open_seek->priv)) break;
-
- // ok
- state = TB_STATE_OK;
-
- } while (0);
-
- // failed?
- if (state != TB_STATE_OK)
- {
- // done func
- ok = open_seek->func(http, state, 0, open_seek->priv);
- }
-
- // ok?
- return ok;
-}
-/*
- * HTTP/1.1 206 Partial Content
- * Date: Fri, 23 Apr 2010 05:25:45 GMT
- * Server: Apache/2.2.9 (Ubuntu) PHP/5.2.6-2ubuntu4.5 with Suhosin-Patch
- * Last-Modified: Mon, 08 Mar 2010 09:58:09 GMT
- * ETag: "6cc014-8f47f-481471a322e40"
- * Accept-Ranges: bytes
- * Content-Length: 586879
- * Content-Range: bytes 0-586878/586879
- * Connection: close
- * Content-Type: application/x-shockwave-flash
- */
-static tb_bool_t tb_aicp_http_head_resp_done(tb_aicp_http_impl_t* impl)
-{
- // check
- tb_assert_and_check_return_val(impl && impl->sstream, tb_false);
-
- // the line and size
- tb_char_t const* line = tb_string_cstr(&impl->line_data);
- tb_size_t size = tb_string_size(&impl->line_data);
- tb_assert_and_check_return_val(line && size, tb_false);
-
- // the first line?
- tb_char_t const* p = line;
- if (!impl->line_size)
- {
- // check http response
- if (tb_strnicmp(p, "HTTP/1.", 7))
- {
- // failed
- tb_assert(0);
- return tb_false;
- }
-
- // seek to the http version
- p += 7;
- tb_assert_and_check_return_val(*p, tb_false);
-
- // parse version
- tb_assert_and_check_return_val((*p - '0') < 2, tb_false);
- impl->status.version = *p - '0';
-
- // seek to the http code
- p++; while (tb_isspace(*p)) p++;
-
- // parse code
- tb_assert_and_check_return_val(*p && tb_isdigit(*p), tb_false);
- impl->status.code = tb_stou32(p);
-
- // save state
- if (impl->status.code == 200 || impl->status.code == 206)
- impl->status.state = TB_STATE_OK;
- else if (impl->status.code == 204)
- impl->status.state = TB_STATE_HTTP_RESPONSE_204;
- else if (impl->status.code >= 300 && impl->status.code <= 307)
- impl->status.state = TB_STATE_HTTP_RESPONSE_300 + (impl->status.code - 300);
- else if (impl->status.code >= 400 && impl->status.code <= 416)
- impl->status.state = TB_STATE_HTTP_RESPONSE_400 + (impl->status.code - 400);
- else if (impl->status.code >= 500 && impl->status.code <= 507)
- impl->status.state = TB_STATE_HTTP_RESPONSE_500 + (impl->status.code - 500);
- else impl->status.state = TB_STATE_HTTP_RESPONSE_UNK;
-
- // check state code: 4xx & 5xx
- if (impl->status.code >= 400 && impl->status.code < 600) return tb_false;
- }
- // key: value?
- else
- {
- // seek to value
- while (*p && *p != ':') p++;
- tb_assert_and_check_return_val(*p, tb_false);
- p++; while (*p && tb_isspace(*p)) p++;
-
- // no value
- tb_check_return_val(*p, tb_true);
-
- // parse content size
- if (!tb_strnicmp(line, "Content-Length", 14))
- {
- impl->status.content_size = tb_stou64(p);
- if (impl->status.document_size < 0)
- impl->status.document_size = impl->status.content_size;
- }
- // parse content range: "bytes $from-$to/$document_size"
- else if (!tb_strnicmp(line, "Content-Range", 13))
- {
- tb_hize_t from = 0;
- tb_hize_t to = 0;
- tb_hize_t document_size = 0;
- if (!tb_strncmp(p, "bytes ", 6))
- {
- p += 6;
- from = tb_stou64(p);
- while (*p && *p != '-') p++;
- if (*p && *p++ == '-') to = tb_stou64(p);
- while (*p && *p != '/') p++;
- if (*p && *p++ == '/') document_size = tb_stou64(p);
- }
- // no stream, be able to seek
- impl->status.bseeked = 1;
- impl->status.document_size = document_size;
- if (impl->status.content_size < 0)
- {
- if (from && to > from) impl->status.content_size = to - from;
- else if (!from && to) impl->status.content_size = to;
- else if (from && !to && document_size > from) impl->status.content_size = document_size - from;
- else impl->status.content_size = document_size;
- }
- }
- // parse accept-ranges: "bytes "
- else if (!tb_strnicmp(line, "Accept-Ranges", 13))
- {
- // no stream, be able to seek
- impl->status.bseeked = 1;
- }
- // parse content type
- else if (!tb_strnicmp(line, "Content-Type", 12))
- {
- tb_string_cstrcpy(&impl->status.content_type, p);
- tb_assert_and_check_return_val(tb_string_size(&impl->status.content_type), tb_false);
- }
- // parse transfer encoding
- else if (!tb_strnicmp(line, "Transfer-Encoding", 17))
- {
- if (!tb_stricmp(p, "chunked")) impl->status.bchunked = 1;
- }
- // parse content encoding
- else if (!tb_strnicmp(line, "Content-Encoding", 16))
- {
- if (!tb_stricmp(p, "gzip")) impl->status.bgzip = 1;
- else if (!tb_stricmp(p, "deflate")) impl->status.bdeflate = 1;
- }
- // parse location
- else if (!tb_strnicmp(line, "Location", 8))
- {
- // redirect? check code: 301 - 307
- tb_assert_and_check_return_val(impl->status.code > 300 && impl->status.code < 308, tb_false);
-
- // save location
- tb_string_cstrcpy(&impl->status.location, p);
- }
- // parse connection
- else if (!tb_strnicmp(line, "Connection", 10))
- {
- // keep alive?
- impl->status.balived = !tb_stricmp(p, "close")? 0 : 1;
-
- // ctrl stream for sock
- if (!tb_async_stream_ctrl(impl->sstream, TB_STREAM_CTRL_SOCK_KEEP_ALIVE, impl->status.balived? tb_true : tb_false)) return tb_false;
- }
- // parse cookies
- else if (impl->option.cookies && !tb_strnicmp(line, "Set-Cookie", 10))
- {
- // the host
- tb_char_t const* host = tb_null;
- tb_aicp_http_ctrl((tb_aicp_http_ref_t)impl, TB_HTTP_OPTION_GET_HOST, &host);
-
- // the path
- tb_char_t const* path = tb_null;
- tb_aicp_http_ctrl((tb_aicp_http_ref_t)impl, TB_HTTP_OPTION_GET_PATH, &path);
-
- // is ssl?
- tb_bool_t bssl = tb_false;
- tb_aicp_http_ctrl((tb_aicp_http_ref_t)impl, TB_HTTP_OPTION_GET_SSL, &bssl);
-
- // set cookies
- tb_cookies_set(impl->option.cookies, host, path, bssl, p);
- }
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_aicp_http_open_func(tb_aicp_http_impl_t* impl, tb_size_t state, tb_aicp_http_open_func_t func, tb_cpointer_t priv);
-static tb_bool_t tb_aicp_http_head_redt_func(tb_async_stream_ref_t stream, tb_size_t state, tb_byte_t const* data, tb_size_t real, tb_size_t size, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)priv;
- tb_assert_and_check_return_val(impl && impl->stream && impl->func.open, tb_false);
-
- // trace
- tb_trace_d("head: redt: real: %lu, size: %lu, state: %s", real, size, tb_state_cstr(state));
-
- // done
- do
- {
- // killed?
- if (TB_STATE_KILLING == tb_atomic_get(&impl->state))
- {
- state = TB_STATE_KILLED;
- break;
- }
-
- // ok?
- if (state == TB_STATE_OK)
- {
- // save read
- impl->content_read += real;
-
- // continue?
- if (impl->status.content_size < 0 || impl->content_read < (tb_hize_t)impl->status.content_size) return tb_true;
- }
-
- // ok?
- tb_check_break(state == TB_STATE_OK || state == TB_STATE_CLOSED);
-
- // redirect failed
- state = TB_STATE_HTTP_REDIRECT_FAILED;
-
- // done location url
- tb_char_t const* location = tb_string_cstr(&impl->status.location);
- tb_assert_and_check_break(location);
-
- // trace
- tb_trace_d("redirect: %s", location);
-
- // only file path?
- if (tb_url_protocol_probe(location) == TB_URL_PROTOCOL_FILE) tb_url_path_set(&impl->option.url, location);
- // full url?
- else
- {
- // set url
- if (!tb_url_cstr_set(&impl->option.url, location)) break;
- }
-
- // done open
- if (!tb_aicp_http_open_done(impl)) break;
-
- // ok
- return tb_false;
-
- } while (0);
-
- // done func
- tb_aicp_http_open_func(impl, state, impl->func.open, impl->priv);
-
- // break
- return tb_false;
-}
-static tb_bool_t tb_aicp_http_head_read_func(tb_async_stream_ref_t stream, tb_size_t state, tb_byte_t const* data, tb_size_t real, tb_size_t size, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)priv;
- tb_assert_and_check_return_val(impl && impl->stream && impl->func.open, tb_false);
-
- // trace
- tb_trace_d("head: read: %s, real: %lu, size: %lu, state: %s", tb_url_cstr(&impl->option.url), real, size, tb_state_cstr(state));
-
- // done
- do
- {
- // ok?
- tb_check_break(state == TB_STATE_OK);
-
- // reset state
- state = TB_STATE_UNKNOWN_ERROR;
-
- // walk
- tb_long_t ok = 0;
- tb_char_t ch = '\0';
- tb_char_t const* p = (tb_char_t const*)data;
- tb_char_t const* e = p + real;
- while (p < e)
- {
- // the char
- ch = *p++;
-
- // error end?
- if (!ch)
- {
- ok = -1;
- tb_assert(0);
- break;
- }
-
- // append char to line
- if (ch != '\n') tb_string_chrcat(&impl->line_data, ch);
- // is line end?
- else
- {
- // strip '\r' if exists
- tb_char_t const* pb = tb_string_cstr(&impl->line_data);
- tb_size_t pn = tb_string_size(&impl->line_data);
- if (!pb || !pn)
- {
- ok = -1;
- tb_assert(0);
- break;
- }
-
- if (pb[pn - 1] == '\r')
- tb_string_strip(&impl->line_data, pn - 1);
-
- // trace
- tb_trace_d("response: %s", pb);
-
- // do callback
- if (impl->option.head_func && !impl->option.head_func(pb, impl->option.head_priv))
- {
- ok = -1;
- tb_assert(0);
- break;
- }
-
- // end?
- if (!tb_string_size(&impl->line_data))
- {
- // ok
- ok = 1;
- break;
- }
-
- // done the head response
- if (!tb_aicp_http_head_resp_done(impl))
- {
- // save the error state
- if (impl->status.state != TB_STATE_OK) state = impl->status.state;
-
- // error
- ok = -1;
- break;
- }
-
- // clear line data
- tb_string_clear(&impl->line_data);
-
- // line++
- impl->line_size++;
- }
- }
-
- // continue ?
- if (!ok) return tb_true;
- // end?
- else if (ok > 0)
- {
- // trace
- tb_trace_d("head: read: end, left: %lu", e - p);
-
- // trace
- tb_trace_d("response: ok");
-
- // redirect?
- if (tb_string_size(&impl->status.location) && impl->redirect_tryn++ < impl->option.redirect)
- {
- // save the redirect read
- impl->content_read = e - p;
-
- // read the left data
- if (impl->status.content_size < 0 || impl->content_read < (tb_hize_t)impl->status.content_size)
- {
- if (!tb_async_stream_read(impl->stream, 0, tb_aicp_http_head_redt_func, impl)) break;
- }
- // no left data, redirect it directly
- else tb_aicp_http_head_redt_func(impl->stream, TB_STATE_OK, tb_null, 0, 0, impl);
- return tb_false;
- }
-
- // switch to cstream if chunked
- if (impl->status.bchunked)
- {
- // init cstream
- if (impl->cstream)
- {
- if (!tb_async_stream_ctrl(impl->cstream, TB_STREAM_CTRL_FLTR_SET_STREAM, impl->stream)) break;
- }
- else impl->cstream = tb_async_stream_init_filter_from_chunked(impl->stream, tb_true);
- tb_assert_and_check_break(impl->cstream);
-
- // push the left data to filter
- if (p < e)
- {
- // the filter
- tb_filter_ref_t filter = tb_null;
- if (!tb_async_stream_ctrl(impl->cstream, TB_STREAM_CTRL_FLTR_GET_FILTER, &filter)) break;
- tb_assert_and_check_break(filter);
-
- // push data
- if (!tb_filter_push(filter, (tb_byte_t const*)p, e - p)) break;
- p = e;
- }
-
- // try to open cstream directly, because the stream have been opened
- if (!tb_async_stream_open_try(impl->cstream)) break;
-
- // using cstream
- impl->stream = impl->cstream;
-
- // disable seek
- impl->status.bseeked = 0;
- }
-
- // switch to zstream if gzip or deflate
- if (impl->option.bunzip && (impl->status.bgzip || impl->status.bdeflate))
- {
-#ifdef TB_CONFIG_PACKAGE_HAVE_ZLIB
- // init zstream
- if (impl->zstream)
- {
- if (!tb_async_stream_ctrl(impl->zstream, TB_STREAM_CTRL_FLTR_SET_STREAM, impl->stream)) break;
- }
- else impl->zstream = tb_async_stream_init_filter_from_zip(impl->stream, impl->status.bgzip? TB_ZIP_ALGO_GZIP : TB_ZIP_ALGO_ZLIB, TB_ZIP_ACTION_INFLATE);
- tb_assert_and_check_break(impl->zstream);
-
- // the filter
- tb_filter_ref_t filter = tb_null;
- if (!tb_async_stream_ctrl(impl->zstream, TB_STREAM_CTRL_FLTR_GET_FILTER, &filter)) break;
- tb_assert_and_check_break(filter);
-
- // ctrl filter
- if (!tb_filter_ctrl(filter, TB_FILTER_CTRL_ZIP_SET_ALGO, impl->status.bgzip? TB_ZIP_ALGO_GZIP : TB_ZIP_ALGO_ZLIB, TB_ZIP_ACTION_INFLATE)) break;
-
- // limit the filter input size
- if (impl->status.content_size > 0) tb_filter_limit(filter, impl->status.content_size);
-
- // push the left data to filter
- if (p < e)
- {
- // push data
- if (!tb_filter_push(filter, (tb_byte_t const*)p, e - p)) break;
- p = e;
- }
-
- // try to open zstream directly, because the stream have been opened
- if (!tb_async_stream_open_try(impl->zstream)) break;
-
- // using zstream
- impl->stream = impl->zstream;
-
- // disable seek
- impl->status.bseeked = 0;
-#else
- // trace
- tb_trace_w("gzip is not supported now! please enable it from config if you need it.");
-
- // not supported
- state = TB_STATE_HTTP_GZIP_NOT_SUPPORTED;
- break;
-#endif
- }
-
- // cache the left data
- if (p < e) tb_buffer_memncat(&impl->cache_data, (tb_byte_t const*)p, e - p);
- p = e;
-
- // ok
- state = TB_STATE_OK;
-
- // dump status
-#if defined(__tb_debug__) && TB_TRACE_MODULE_DEBUG
- tb_http_status_dump(&impl->status);
-#endif
- }
- // error?
- else
- {
- // trace
- tb_trace_d("head: read: %s, error, state: %s", tb_url_cstr(&impl->option.url), tb_state_cstr(state));
- }
-
- } while (0);
-
- // done func
- tb_aicp_http_open_func(impl, state, impl->func.open, impl->priv);
-
- // break
- return tb_false;
-}
-static tb_bool_t tb_aicp_http_head_post_func(tb_size_t state, tb_hize_t offset, tb_hong_t size, tb_hize_t save, tb_size_t rate, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)priv;
- tb_assert_and_check_return_val(impl && impl->stream && impl->func.open, tb_false);
-
- // trace
- tb_trace_d("head: post: percent: %llu%%, size: %lu, state: %s", size > 0? (offset * 100 / size) : 0, save, tb_state_cstr(state));
-
- // done
- tb_bool_t bpost = tb_false;
- do
- {
- // done func
- if (impl->option.post_func && !impl->option.post_func(state, offset, size, save, rate, impl->option.post_priv))
- {
- state = TB_STATE_UNKNOWN_ERROR;
- break;
- }
-
- // ok? continue to post
- if (state == TB_STATE_OK) bpost = tb_true;
- // closed? read head
- else if (state == TB_STATE_CLOSED)
- {
- // reset state
- state = TB_STATE_UNKNOWN_ERROR;
-
- // clear line size
- impl->line_size = 0;
-
- // clear line data
- tb_string_clear(&impl->line_data);
-
- // clear cache data
- tb_buffer_clear(&impl->cache_data);
- impl->cache_read = 0;
-
- // post read
- if (!tb_async_stream_read(impl->stream, 0, tb_aicp_http_head_read_func, impl)) break;
- }
- // failed?
- else break;
-
- // ok
- state = TB_STATE_OK;
-
- } while (0);
-
- // failed?
- if (state != TB_STATE_OK)
- {
- // done func
- tb_aicp_http_open_func(impl, state, impl->func.open, impl->priv);
- }
-
- // ok?
- return bpost;
-}
-static tb_bool_t tb_aicp_http_head_writ_func(tb_async_stream_ref_t stream, tb_size_t state, tb_byte_t const* data, tb_size_t real, tb_size_t size, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)priv;
- tb_assert_and_check_return_val(impl && impl->stream && impl->func.open, tb_false);
-
- // trace
- tb_trace_d("head: writ: %s, real: %lu, size: %lu, state: %s", tb_url_cstr(&impl->option.url), real, size, tb_state_cstr(state));
-
- // done
- tb_bool_t bwrit = tb_false;
- do
- {
- // ok?
- tb_check_break(state == TB_STATE_OK);
-
- // killed?
- if (TB_STATE_KILLING == tb_atomic_get(&impl->state))
- {
- state = TB_STATE_KILLED;
- break;
- }
-
- // reset state
- state = TB_STATE_UNKNOWN_ERROR;
-
- // not finished? continue it
- if (real < size)
- {
- // continue to writ
- bwrit = tb_true;
- }
- // finished? post data
- else if (impl->option.method == TB_HTTP_METHOD_POST)
- {
- // check
- tb_assert_and_check_break(impl->transfer);
-
- // post data
- if (!tb_async_transfer_done(impl->transfer, tb_aicp_http_head_post_func, impl)) break;
- }
- // finished? read data
- else
- {
- // clear line size
- impl->line_size = 0;
-
- // clear line data
- tb_string_clear(&impl->line_data);
-
- // clear cache data
- tb_buffer_clear(&impl->cache_data);
- impl->cache_read = 0;
-
- // post read
- if (!tb_async_stream_read(impl->stream, 0, tb_aicp_http_head_read_func, impl)) break;
- }
-
- // ok
- state = TB_STATE_OK;
-
- } while (0);
-
- // failed?
- if (state != TB_STATE_OK)
- {
- // done func
- tb_aicp_http_open_func(impl, state, impl->func.open, impl->priv);
- }
-
- // ok?
- return bwrit;
-}
-static tb_bool_t tb_aicp_http_post_open_func(tb_size_t state, tb_hize_t offset, tb_hong_t size, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)priv;
- tb_assert_and_check_return_val(impl && impl->stream && impl->func.open, tb_false);
-
- // trace
- tb_trace_d("post: open: offset: %lu, size: %lu, state: %s", offset, size, tb_state_cstr(state));
-
- // done
- tb_bool_t ok = tb_true;
- do
- {
- // ok?
- tb_check_break(state == TB_STATE_OK);
-
- // reset state
- state = TB_STATE_UNKNOWN_ERROR;
-
- // no post size?
- if (size < 0)
- {
- state = TB_STATE_HTTP_POST_FAILED;
- break;
- }
-
- // the head data and size
- tb_size_t head_size = 0;
- tb_char_t const* head_data = tb_aicp_http_head_format(impl, size, &head_size, &state);
- tb_check_break(head_data && head_size);
-
- // trace
- tb_trace_d("request[%lu]:\n%s", head_size, head_data);
-
- // post writ head
- if (!tb_async_stream_writ(impl->stream, (tb_byte_t const*)head_data, head_size, tb_aicp_http_head_writ_func, impl)) break;
-
- // ok
- state = TB_STATE_OK;
-
- } while (0);
-
- // failed?
- if (state != TB_STATE_OK)
- {
- // done func
- tb_aicp_http_open_func(impl, state, impl->func.open, impl->priv);
- }
-
- // ok?
- return ok;
-}
-static tb_bool_t tb_aicp_http_sock_open_func(tb_async_stream_ref_t stream, tb_size_t state, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)priv;
- tb_assert_and_check_return_val(impl && impl->stream && impl->func.open, tb_false);
-
- // trace
- tb_trace_d("sock: open: state: %s", tb_state_cstr(state));
-
- // done
- tb_bool_t ok = tb_true;
- do
- {
- // ok?
- tb_check_break(state == TB_STATE_OK);
-
- // killed?
- if (TB_STATE_KILLING == tb_atomic_get(&impl->state))
- {
- state = TB_STATE_KILLED;
- break;
- }
-
- // reset state
- state = TB_STATE_UNKNOWN_ERROR;
-
- // get?
- if (impl->option.method == TB_HTTP_METHOD_GET)
- {
- // the head data and size
- tb_size_t head_size = 0;
- tb_char_t const* head_data = tb_aicp_http_head_format(impl, 0, &head_size, tb_null);
- tb_check_break(head_data && head_size);
-
- // trace
- tb_trace_d("request:\n%s", head_data);
-
- // post writ head
- ok = tb_async_stream_open_writ(impl->stream, (tb_byte_t const*)head_data, head_size, tb_aicp_http_head_writ_func, impl);
- }
- // post?
- else if (impl->option.method == TB_HTTP_METHOD_POST)
- {
- // init transfer
- if (!impl->transfer) impl->transfer = tb_async_transfer_init(tb_async_stream_aicp(impl->stream), tb_false);
- tb_assert_and_check_break(impl->transfer);
-
- // init transfer istream
- tb_char_t const* url = tb_url_cstr(&impl->option.post_url);
- if (impl->option.post_data && impl->option.post_size)
- {
- if (!tb_async_transfer_init_istream_from_data(impl->transfer, impl->option.post_data, impl->option.post_size)) break;
- }
- else if (url)
- {
- if (!tb_async_transfer_init_istream_from_url(impl->transfer, url)) break;
- }
-
- // init transfer ostream
- if (!tb_async_transfer_init_ostream(impl->transfer, impl->stream)) break;
-
- // limit rate
- if (impl->option.post_lrate) tb_async_transfer_limitrate(impl->transfer, impl->option.post_lrate);
-
- // open transfer
- ok = tb_async_transfer_open(impl->transfer, 0, tb_aicp_http_post_open_func, impl);
- }
- else tb_assert_and_check_break(0);
-
- // ok
- state = TB_STATE_OK;
-
- } while (0);
-
- // failed?
- if (state != TB_STATE_OK)
- {
- // done func
- tb_aicp_http_open_func(impl, state, impl->func.open, impl->priv);
- }
-
- // ok?
- return ok;
-}
-static tb_bool_t tb_aicp_http_read_func(tb_async_stream_ref_t stream, tb_size_t state, tb_byte_t const* data, tb_size_t real, tb_size_t size, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)priv;
- tb_assert_and_check_return_val(impl && impl->stream && impl->func.read, tb_false);
-
- // ok? update the content read
- if (state == TB_STATE_OK) impl->content_read += real;
-
- // trace
- tb_trace_d("read: %s, real: %lu, offset: %llu <? %llu, state: %s", tb_url_cstr(&impl->option.url), real, impl->content_read, impl->status.content_size, tb_state_cstr(state));
-
- // done func
- tb_bool_t ok = impl->func.read((tb_aicp_http_ref_t)impl, state, data, real, size, impl->priv);
-
- // end?
- if (ok && state == TB_STATE_OK && impl->status.content_size >= 0 && impl->content_read >= (tb_hize_t)impl->status.content_size)
- {
- // done func: closed
- impl->func.read((tb_aicp_http_ref_t)impl, TB_STATE_CLOSED, data, 0, size, impl->priv);
-
- // break reading
- ok = tb_false;
- }
-
- // ok?
- return ok;
-}
-static tb_bool_t tb_aicp_http_task_func(tb_async_stream_ref_t stream, tb_size_t state, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)priv;
- tb_assert_and_check_return_val(impl && impl->stream && impl->func.task, tb_false);
-
- // trace
- tb_trace_d("task: state: %s", tb_state_cstr(state));
-
- // done func
- return impl->func.task((tb_aicp_http_ref_t)impl, state, impl->priv);
-}
-static tb_void_t tb_aicp_http_clos_clear(tb_aicp_http_impl_t* impl)
-{
- // check
- tb_assert_and_check_return(impl && impl->stream);
-
- // reset stream
- impl->stream = impl->sstream;
-
- // clear the content read size
- impl->content_read = 0;
-
- // closed
- tb_atomic_set(&impl->state, TB_STATE_CLOSED);
-}
-static tb_void_t tb_aicp_http_clos_func(tb_async_stream_ref_t stream, tb_size_t state, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)priv;
- tb_assert_and_check_return(impl && impl->stream && impl->func.clos);
-
- // trace
- tb_trace_d("clos: notify: ..");
-
- // clear it
- tb_aicp_http_clos_clear(impl);
-
- // done func
- impl->func.clos((tb_aicp_http_ref_t)impl, state, impl->priv);
-
- // trace
- tb_trace_d("clos: notify: ok");
-}
-static tb_void_t tb_aicp_http_clos_transfer_func(tb_size_t state, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)priv;
- tb_assert_and_check_return(impl && impl->stream && impl->func.clos);
-
- // trace
- tb_trace_d("clos: transfer: notify: ..");
-
- // done func directly, because the stream have been closed by transfer
- tb_aicp_http_clos_func(impl->stream, state, impl);
-
- // trace
- tb_trace_d("clos: transfer: notify: ok");
-}
-static tb_void_t tb_aicp_http_clos_opening_func(tb_aicp_http_ref_t http, tb_size_t state, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)http;
- tb_assert_and_check_return(impl && impl->clos_opening.func);
-
- // trace
- tb_trace_d("clos: opening");
-
- // done
- impl->status.state = impl->clos_opening.state;
- impl->clos_opening.func(http, impl->status.state, &impl->status, impl->clos_opening.priv);
-}
-static tb_void_t tb_aicp_http_open_clos(tb_async_stream_ref_t stream, tb_size_t state, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)priv;
- tb_assert_and_check_return(impl && impl->stream && impl->func.open);
-
- // done
- tb_bool_t ok = tb_false;
- do
- {
- // check
- tb_assert_and_check_break(state == TB_STATE_OK);
-
- // killed?
- if (TB_STATE_KILLING == tb_atomic_get(&impl->state))
- {
- state = TB_STATE_KILLED;
- break;
- }
-
- // reset state
- state = TB_STATE_HTTP_UNKNOWN_ERROR;
-
- // reset stream
- impl->stream = impl->sstream;
-
- // the host is changed?
- tb_bool_t host_changed = tb_true;
- tb_char_t const* host_old = tb_null;
- tb_char_t const* host_new = tb_url_host(&impl->option.url);
- tb_async_stream_ctrl(impl->stream, TB_STREAM_CTRL_GET_HOST, &host_old);
- if (host_old && host_new && !tb_stricmp(host_old, host_new)) host_changed = tb_false;
-
- // trace
- tb_trace_d("connect: host: %s", host_changed? "changed" : "keep");
-
- // ctrl stream
- if (!tb_async_stream_ctrl(impl->stream, TB_STREAM_CTRL_SET_URL, tb_url_cstr(&impl->option.url))) break;
- if (!tb_async_stream_ctrl(impl->stream, TB_STREAM_CTRL_SET_TIMEOUT, impl->option.timeout)) break;
-
- // dump option
-#if defined(__tb_debug__) && TB_TRACE_MODULE_DEBUG
- tb_http_option_dump(&impl->option);
-#endif
-
- // clear status
- tb_http_status_cler(&impl->status, host_changed);
-
- // open the stream
- ok = tb_async_stream_open(impl->stream, tb_aicp_http_sock_open_func, impl);
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // done func
- tb_aicp_http_open_func(impl, state, impl->func.open, impl->priv);
- }
-}
-static tb_void_t tb_aicp_http_open_clos_transfer(tb_size_t state, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)priv;
- tb_assert_and_check_return(impl && impl->stream);
-
- // done func directly, because the stream have been closed by transfer
- tb_aicp_http_open_clos(impl->stream, state, impl);
-}
-static tb_bool_t tb_aicp_http_open_done(tb_aicp_http_impl_t* impl)
-{
- // check
- tb_assert_and_check_return_val(impl && impl->stream && impl->func.open, tb_false);
-
- // close transfer
- if (impl->transfer) return tb_async_transfer_clos(impl->transfer, tb_aicp_http_open_clos_transfer, impl);
- // close stream
- else return tb_async_stream_clos(impl->stream, tb_aicp_http_open_clos, impl);
-}
-static tb_bool_t tb_aicp_http_open_func(tb_aicp_http_impl_t* impl, tb_size_t state, tb_aicp_http_open_func_t func, tb_cpointer_t priv)
-{
- // check
- tb_assert_and_check_return_val(impl, tb_false);
-
- // ok?
- tb_bool_t ok = tb_true;
- if (state == TB_STATE_OK)
- {
- // opened
- tb_atomic_set(&impl->state, TB_STATE_OPENED);
-
- // done func
- impl->status.state = state;
- if (func) ok = func((tb_aicp_http_ref_t)impl, state, &impl->status, priv);
- }
- // failed?
- else
- {
- // init func and state
- impl->clos_opening.func = func;
- impl->clos_opening.priv = priv;
- impl->clos_opening.state = state;
-
- // close it
- ok = tb_aicp_http_clos((tb_aicp_http_ref_t)impl, tb_aicp_http_clos_opening_func, tb_null);
- }
-
- // ok?
- return ok;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-tb_aicp_http_ref_t tb_aicp_http_init(tb_aicp_ref_t aicp)
-{
- // check
- tb_assert_and_check_return_val(aicp, tb_null);
-
- // done
- tb_bool_t ok = tb_false;
- tb_aicp_http_impl_t* impl = tb_null;
- do
- {
- // make impl
- impl = tb_malloc0_type(tb_aicp_http_impl_t);
- tb_assert_and_check_break(impl);
-
- // init state
- impl->state = TB_STATE_CLOSED;
-
- // init stream
- impl->stream = impl->sstream = tb_async_stream_init_sock(aicp);
- tb_assert_and_check_break(impl->stream);
-
- // init head
- impl->head = tb_hash_map_init(8, tb_element_str(tb_false), tb_element_str(tb_false));
- tb_assert_and_check_break(impl->head);
-
- // init cookies data
- if (!tb_string_init(&impl->cookies)) break;
-
- // init line data
- if (!tb_string_init(&impl->line_data)) break;
-
- // init cache data
- if (!tb_buffer_init(&impl->cache_data)) break;
- impl->cache_read = 0;
-
- // init option
- if (!tb_http_option_init(&impl->option)) break;
-
- // init status
- if (!tb_http_status_init(&impl->status)) break;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- if (impl) tb_aicp_http_exit((tb_aicp_http_ref_t)impl);
- impl = tb_null;
- }
-
- // ok?
- return (tb_aicp_http_ref_t)impl;
-}
-tb_void_t tb_aicp_http_kill(tb_aicp_http_ref_t http)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)http;
- tb_assert_and_check_return(impl);
-
- // kill it
- tb_size_t state = tb_atomic_fetch_and_set(&impl->state, TB_STATE_KILLING);
- tb_check_return(state != TB_STATE_KILLING);
-
- // trace
- tb_trace_d("kill: ..");
-
- // kill transfer
- if (impl->transfer) tb_async_transfer_kill(impl->transfer);
-
- // kill stream
- if (impl->stream) tb_async_stream_kill(impl->stream);
-}
-tb_bool_t tb_aicp_http_exit(tb_aicp_http_ref_t http)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)http;
- tb_assert_and_check_return_val(impl, tb_false);
-
- // trace
- tb_trace_d("exit: ..");
-
- // kill it first
- tb_aicp_http_kill(http);
-
- // try closing it
- tb_size_t tryn = 30;
- tb_bool_t ok = tb_false;
- while (!(ok = tb_aicp_http_clos_try(http)) && tryn--)
- {
- // wait some time
- tb_msleep(200);
- }
-
- // close failed?
- if (!ok)
- {
- // trace
- tb_trace_e("exit: %s: failed!", tb_url_cstr(&impl->option.url));
- return tb_false;
- }
-
- // exit transfer
- if (impl->transfer) tb_async_transfer_exit(impl->transfer);
- impl->transfer = tb_null;
-
- // exit zstream
- if (impl->zstream) tb_async_stream_exit(impl->zstream);
- impl->zstream = tb_null;
-
- // exit cstream
- if (impl->cstream) tb_async_stream_exit(impl->cstream);
- impl->cstream = tb_null;
-
- // exit sstream
- if (impl->sstream) tb_async_stream_exit(impl->sstream);
- impl->sstream = tb_null;
-
- // exit stream
- impl->stream = tb_null;
-
- // exit status
- tb_http_status_exit(&impl->status);
-
- // exit option
- tb_http_option_exit(&impl->option);
-
- // exit line data
- tb_string_exit(&impl->line_data);
-
- // exit cache data
- tb_buffer_exit(&impl->cache_data);
-
- // exit cookies data
- tb_string_exit(&impl->cookies);
-
- // exit head
- if (impl->head) tb_hash_map_exit(impl->head);
- impl->head = tb_null;
-
- // free it
- tb_free(impl);
-
- // trace
- tb_trace_d("exit: ok");
-
- // ok
- return tb_true;
-}
-tb_bool_t tb_aicp_http_open(tb_aicp_http_ref_t http, tb_aicp_http_open_func_t func, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)http;
- tb_assert_and_check_return_val(impl && func, tb_false);
-
- // set opening
- tb_size_t state = tb_atomic_fetch_and_pset(&impl->state, TB_STATE_CLOSED, TB_STATE_OPENING);
-
- // opened? done func directly
- if (state == TB_STATE_OPENED)
- {
- impl->status.state = TB_STATE_OK;
- func(http, impl->status.state, &impl->status, priv);
- return tb_true;
- }
-
- // must be closed
- tb_assert_and_check_return_val(state == TB_STATE_CLOSED, tb_false);
-
- // init open
- impl->func.open = func;
- impl->priv = priv;
-
- // clear redirect
- impl->redirect_tryn = 0;
-
- // done open
- return tb_aicp_http_open_done(impl);
-}
-tb_bool_t tb_aicp_http_clos(tb_aicp_http_ref_t http, tb_aicp_http_clos_func_t func, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)http;
- tb_assert_and_check_return_val(impl && impl->stream && func, tb_false);
-
- // trace
- tb_trace_d("clos: ..");
-
- // try closing ok?
- if (tb_aicp_http_clos_try(http))
- {
- // done func
- func(http, TB_STATE_OK, priv);
- return tb_true;
- }
-
- // init func
- impl->func.clos = func;
- impl->priv = priv;
-
- // close transfer
- if (impl->transfer) return tb_async_transfer_clos(impl->transfer, tb_aicp_http_clos_transfer_func, impl);
- // close stream
- else return tb_async_stream_clos(impl->stream, tb_aicp_http_clos_func, impl);
-}
-tb_bool_t tb_aicp_http_clos_try(tb_aicp_http_ref_t http)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)http;
- tb_assert_and_check_return_val(impl && impl->stream, tb_false);
-
- // trace
- tb_trace_d("clos: try: %s: ..", tb_url_cstr(&impl->option.url));
-
- // done
- tb_bool_t ok = tb_false;
- do
- {
- // closed?
- if (TB_STATE_CLOSED == tb_atomic_get(&impl->state))
- {
- ok = tb_true;
- break;
- }
-
- // try closing transfer
- if (impl->transfer && !tb_async_transfer_clos_try(impl->transfer)) break;
-
- // try closing it
- if (!tb_async_stream_clos_try(impl->stream)) break;
-
- // clear it
- tb_aicp_http_clos_clear(impl);
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // trace
- tb_trace_d("clos: try: %s: %s", tb_url_cstr(&impl->option.url), ok? "ok" : "no");
-
- // ok?
- return ok;
-}
-tb_bool_t tb_aicp_http_read(tb_aicp_http_ref_t http, tb_size_t size, tb_aicp_http_read_func_t func, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)http;
- tb_assert_and_check_return_val(impl && impl->stream && func, tb_false);
-
- // post read
- return tb_aicp_http_read_after(http, 0, size, func, priv);
-}
-tb_bool_t tb_aicp_http_read_after(tb_aicp_http_ref_t http, tb_size_t delay, tb_size_t size, tb_aicp_http_read_func_t func, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)http;
- tb_assert_and_check_return_val(impl && impl->stream && func, tb_false);
-
- // check state
- tb_assert_and_check_return_val(TB_STATE_OPENED == tb_atomic_get(&impl->state), tb_false);
-
- // read the cache data first, note: must be reentrant
- tb_byte_t const* cache_data = tb_buffer_data(&impl->cache_data);
- tb_size_t cache_size = tb_buffer_size(&impl->cache_data);
- if (cache_data && cache_size && impl->cache_read < cache_size)
- {
- // read cache
- impl->cache_read = cache_size;
-
- // update the content read
- impl->content_read += cache_size;
-
- // done func
- tb_bool_t ok = func(http, TB_STATE_OK, cache_data, cache_size, cache_size, priv);
-
- // clear cache data
- tb_buffer_clear(&impl->cache_data);
- impl->cache_read = 0;
-
- // break?
- tb_check_return_val(ok, tb_true);
- }
-
- // init read
- impl->func.read = func;
- impl->priv = priv;
-
- // post read
- return tb_async_stream_read_after(impl->stream, delay, size, tb_aicp_http_read_func, impl);
-}
-tb_bool_t tb_aicp_http_seek(tb_aicp_http_ref_t http, tb_hize_t offset, tb_aicp_http_seek_func_t func, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)http;
- tb_assert_and_check_return_val(impl && impl->stream && func, tb_false);
-
- // set opening
- tb_size_t state = tb_atomic_fetch_and_pset(&impl->state, TB_STATE_CLOSED, TB_STATE_OPENING);
-
- // killed?
- tb_assert_and_check_return_val(state != TB_STATE_KILLING, tb_false);
-
- // done
- tb_bool_t ok = tb_false;
- do
- {
- // trace
- tb_trace_d("seek: %llu", offset);
-
- // init open
- impl->func.open = tb_aicp_http_open_seek_func;
- impl->priv = &impl->open_and.seek;
-
- // init open and seek
- impl->open_and.seek.func = func;
- impl->open_and.seek.priv = priv;
- impl->open_and.seek.offset = offset;
-
- // clear redirect
- impl->redirect_tryn = 0;
-
- // set range
- impl->option.range.bof = offset;
- impl->option.range.eof = impl->status.document_size > 0? impl->status.document_size - 1 : 0;
-
- // done open
- if (!tb_aicp_http_open_done(impl)) break;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // ok?
- return ok;
-}
-tb_bool_t tb_aicp_http_task(tb_aicp_http_ref_t http, tb_size_t delay, tb_aicp_http_task_func_t func, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)http;
- tb_assert_and_check_return_val(impl && impl->stream && func, tb_false);
-
- // check state
- tb_assert_and_check_return_val(TB_STATE_OPENED == tb_atomic_get(&impl->state), tb_false);
-
- // init task
- impl->func.task = func;
- impl->priv = priv;
-
- // post task
- return tb_async_stream_task(impl->stream, delay, tb_aicp_http_task_func, impl);
-}
-tb_bool_t tb_aicp_http_open_read(tb_aicp_http_ref_t http, tb_size_t size, tb_aicp_http_read_func_t func, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)http;
- tb_assert_and_check_return_val(impl && func, tb_false);
-
- // init open and read
- impl->open_and.read.func = func;
- impl->open_and.read.priv = priv;
- impl->open_and.read.size = size;
- return tb_aicp_http_open(http, tb_aicp_http_open_read_func, &impl->open_and.read);
-}
-tb_bool_t tb_aicp_http_open_seek(tb_aicp_http_ref_t http, tb_hize_t offset, tb_aicp_http_seek_func_t func, tb_cpointer_t priv)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)http;
- tb_assert_and_check_return_val(impl && func, tb_false);
-
- // open and seek
- return tb_aicp_http_seek(http, offset, func, priv);
-}
-tb_aicp_ref_t tb_aicp_http_aicp(tb_aicp_http_ref_t http)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)http;
- tb_assert_and_check_return_val(impl && impl->stream, tb_null);
-
- // the aicp
- return tb_async_stream_aicp(impl->stream);
-}
-tb_bool_t tb_aicp_http_ctrl(tb_aicp_http_ref_t http, tb_size_t option, ...)
-{
- // check
- tb_aicp_http_impl_t* impl = (tb_aicp_http_impl_t*)http;
- tb_assert_and_check_return_val(impl && impl->sstream && option, tb_false);
-
- // check
- if (TB_HTTP_OPTION_CODE_IS_SET(option) && !tb_async_stream_is_closed(impl->sstream))
- {
- // abort
- tb_assert(0);
- return tb_false;
- }
-
- // init args
- tb_va_list_t args;
- tb_va_start(args, option);
-
- // done
- tb_bool_t ok = tb_http_option_ctrl(&impl->option, option, args);
-
- // exit args
- tb_va_end(args);
-
- // ok?
- return ok;
-}
diff --git a/core/src/tbox/src/tbox/asio/deprecated/http.h b/core/src/tbox/src/tbox/asio/deprecated/http.h
deleted file mode 100644
index 521f16199..000000000
--- a/core/src/tbox/src/tbox/asio/deprecated/http.h
+++ /dev/null
@@ -1,259 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file http.h
- * @ingroup asio
- *
- */
-#ifndef TB_ASIO_HTTP_H
-#define TB_ASIO_HTTP_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "aicp.h"
-#include "../../network/http.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the aicp http ref type
-typedef __tb_typeref__(aicp_http);
-
-/*! the aicp http open func type
- *
- * @param http the http handle
- * @param state the state
- * @param status the http status
- * @param priv the func private data
- *
- * @return tb_true: ok, tb_false: error, but not break aicp
- */
-typedef tb_bool_t (*tb_aicp_http_open_func_t)(tb_aicp_http_ref_t http, tb_size_t state, tb_http_status_t const* status, tb_cpointer_t priv);
-
-/*! the aicp http open func type
- *
- * @param http the http handle
- * @param state the state
- * @param priv the func private data
- *
- * @return tb_true: ok, tb_false: error, but not break aicp
- */
-typedef tb_void_t (*tb_aicp_http_clos_func_t)(tb_aicp_http_ref_t http, tb_size_t state, tb_cpointer_t priv);
-
-/*! the aicp http read func type
- *
- * @param http the http handle
- * @param state the state
- * @param data the readed data
- * @param real the real size, maybe zero
- * @param size the need size
- * @param priv the func private data
- *
- * @return tb_true: ok and continue it if need, tb_false: break it, but not break aicp
- */
-typedef tb_bool_t (*tb_aicp_http_read_func_t)(tb_aicp_http_ref_t http, tb_size_t state, tb_byte_t const* data, tb_size_t real, tb_size_t size, tb_cpointer_t priv);
-
-/*! the aicp http seek func type
- *
- * @param http the http handle
- * @param state the state
- * @param offset the real offset
- * @param priv the func private data
- *
- * @return tb_true: ok, tb_false: error, but not break aicp
- */
-typedef tb_bool_t (*tb_aicp_http_seek_func_t)(tb_aicp_http_ref_t http, tb_size_t state, tb_hize_t offset, tb_cpointer_t priv);
-
-/*! the aicp http task func type
- *
- * @param http the http handle
- * @param state the state
- * @param priv the func private data
- *
- * @return tb_true: ok, tb_false: error, but not break aicp
- */
-typedef tb_bool_t (*tb_aicp_http_task_func_t)(tb_aicp_http_ref_t http, tb_size_t state, tb_cpointer_t priv);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init the http
- *
- * @param aicp the aicp
- *
- * @return the http
- */
-__tb_deprecated__
-tb_aicp_http_ref_t tb_aicp_http_init(tb_aicp_ref_t aicp);
-
-/*! kill the http
- *
- * @param http the http
- */
-__tb_deprecated__
-tb_void_t tb_aicp_http_kill(tb_aicp_http_ref_t http);
-
-/*! exit the http
- *
- * @param http the http
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_http_exit(tb_aicp_http_ref_t http);
-
-/*! open the http
- *
- * @param http the http
- * @param func the func
- * @param priv the func data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_http_open(tb_aicp_http_ref_t http, tb_aicp_http_open_func_t func, tb_cpointer_t priv);
-
-/*! close the http
- *
- * @param http the http
- * @param func the func
- * @param priv the private data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_http_clos(tb_aicp_http_ref_t http, tb_aicp_http_clos_func_t func, tb_cpointer_t priv);
-
-/*! try closing the http
- *
- * @param http the http
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_http_clos_try(tb_aicp_http_ref_t http);
-
-/*! read the http
- *
- * @param http the http
- * @param size the read size, using the default size if be zero
- * @param func the func
- * @param priv the func data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_http_read(tb_aicp_http_ref_t http, tb_size_t size, tb_aicp_http_read_func_t func, tb_cpointer_t priv);
-
-/*! read the http after the delay time
- *
- * @param http the http
- * @param delay the delay time, ms
- * @param size the read size, using the default size if be zero
- * @param func the func
- * @param priv the func data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_http_read_after(tb_aicp_http_ref_t http, tb_size_t delay, tb_size_t size, tb_aicp_http_read_func_t func, tb_cpointer_t priv);
-
-/*! seek the http
- *
- * @param http the http
- * @param offset the offset
- * @param func the func
- * @param priv the func data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_http_seek(tb_aicp_http_ref_t http, tb_hize_t offset, tb_aicp_http_seek_func_t func, tb_cpointer_t priv);
-
-/*! task the http
- *
- * @param http the http
- * @param delay the delay time, ms
- * @param func the func
- * @param priv the func data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_http_task(tb_aicp_http_ref_t http, tb_size_t delay, tb_aicp_http_task_func_t func, tb_cpointer_t priv);
-
-/*! open and read the http, open it first if not opened
- *
- * @param http the http
- * @param size the read size, using the default size if be zero
- * @param func the func
- * @param priv the func data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_http_open_read(tb_aicp_http_ref_t http, tb_size_t size, tb_aicp_http_read_func_t func, tb_cpointer_t priv);
-
-/*! open and seek the http, open it first if not opened
- *
- * @param http the http
- * @param offset the offset
- * @param func the func
- * @param priv the func data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_http_open_seek(tb_aicp_http_ref_t http, tb_hize_t offset, tb_aicp_http_seek_func_t func, tb_cpointer_t priv);
-
-/*! the http aicp
- *
- * @param http the http
- *
- * @return the aicp
- */
-__tb_deprecated__
-tb_aicp_ref_t tb_aicp_http_aicp(tb_aicp_http_ref_t http);
-
-/*! ctrl the http option
- *
- * @param http the http
- * @param option the http option
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_http_ctrl(tb_aicp_http_ref_t http, tb_size_t option, ...);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/asio/deprecated/impl/aicp_aiop.c b/core/src/tbox/src/tbox/asio/deprecated/impl/aicp_aiop.c
deleted file mode 100644
index 031f0d004..000000000
--- a/core/src/tbox/src/tbox/asio/deprecated/impl/aicp_aiop.c
+++ /dev/null
@@ -1,1795 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file aicp.c
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the aiop ptor type
-typedef struct __tb_aiop_ptor_impl_t
-{
- // the ptor base
- tb_aicp_ptor_impl_t base;
-
- // the wait aiop
- tb_aiop_ref_t aiop;
-
- /* the aice spak
- *
- * index: 0: higher priority for conn, acpt and task
- * index: 1: lower priority for io aice
- */
- tb_queue_ref_t spak[2];
-
- // the spak lock
- tb_spinlock_t lock;
-
- // the spak wait
- tb_semaphore_ref_t wait;
-
- // the spak loop
- tb_thread_ref_t loop;
-
- // the aioe list
- tb_aioe_ref_t list;
-
- // the aioe size
- tb_size_t maxn;
-
- // the timer for task
- tb_timer_ref_t timer;
-
- // the low precision timer for timeout
- tb_ltimer_ref_t ltimer;
-
- // the private data for file
- tb_handle_t fpriv;
-
- // the killing list lock
- tb_spinlock_t klock;
-
- // the killing aico list
- tb_vector_ref_t klist;
-
-}tb_aiop_ptor_impl_t;
-
-// the aiop aico type
-typedef struct __tb_aiop_aico_t
-{
- // the base
- tb_aico_impl_t base;
-
- // the impl
- tb_aiop_ptor_impl_t* impl;
-
- // the aioo
- tb_aioo_ref_t aioo;
-
- // the aice
- tb_aice_t aice;
-
- // the task
- tb_handle_t task;
-
- /* wait ok? avoid spak double aice when wait killed/timeout and ok at same time
- * need lock it using impl->lock
- */
- tb_uint8_t wait_ok : 1;
-
- // is waiting?
- tb_uint8_t waiting : 1;
-
- // is ltimer?
- tb_uint8_t bltimer : 1;
-
-}tb_aiop_aico_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * file declaration
- */
-static tb_bool_t tb_aicp_file_init(tb_aiop_ptor_impl_t* impl);
-static tb_void_t tb_aicp_file_exit(tb_aiop_ptor_impl_t* impl);
-static tb_bool_t tb_aicp_file_addo(tb_aiop_ptor_impl_t* impl, tb_aico_impl_t* aico);
-static tb_void_t tb_aicp_file_kilo(tb_aiop_ptor_impl_t* impl, tb_aico_impl_t* aico);
-static tb_bool_t tb_aicp_file_post(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice);
-static tb_void_t tb_aicp_file_kill(tb_aiop_ptor_impl_t* impl);
-static tb_void_t tb_aicp_file_poll(tb_aiop_ptor_impl_t* impl);
-static tb_long_t tb_aicp_file_spak_read(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice);
-static tb_long_t tb_aicp_file_spak_writ(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice);
-static tb_long_t tb_aicp_file_spak_readv(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice);
-static tb_long_t tb_aicp_file_spak_writv(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice);
-static tb_long_t tb_aicp_file_spak_fsync(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * spak
- */
-static __tb_inline__ tb_size_t tb_aiop_aioe_code(tb_aice_ref_t aice)
-{
- // the aioe code
- static tb_size_t s_code[] =
- {
- TB_AIOE_CODE_NONE
-
- , TB_AIOE_CODE_ACPT //< acpt
- , TB_AIOE_CODE_CONN //< conn
- , TB_AIOE_CODE_RECV //< recv
- , TB_AIOE_CODE_SEND //< send
- , TB_AIOE_CODE_RECV //< urecv
- , TB_AIOE_CODE_SEND //< usend
- , TB_AIOE_CODE_RECV //< recvv
- , TB_AIOE_CODE_SEND //< sendv
- , TB_AIOE_CODE_RECV //< urecvv
- , TB_AIOE_CODE_SEND //< usendv
- , TB_AIOE_CODE_SEND //< sendf
-
- , TB_AIOE_CODE_NONE
- , TB_AIOE_CODE_NONE
- , TB_AIOE_CODE_NONE
- , TB_AIOE_CODE_NONE
- , TB_AIOE_CODE_NONE
-
- , TB_AIOE_CODE_NONE
- };
- tb_assert_and_check_return_val(aice->code && aice->code < tb_arrayn(s_code), TB_AIOE_CODE_NONE);
-
- // the aioe code
- return s_code[aice->code];
-}
-static tb_void_t tb_aiop_spak_work(tb_aiop_ptor_impl_t* impl)
-{
- // check
- tb_assert_and_check_return(impl && impl->wait && impl->base.aicp);
-
- // the worker size
- tb_size_t work = tb_atomic_get(&impl->base.aicp->work);
-
- // the semaphore value
- tb_long_t value = tb_semaphore_value(impl->wait);
-
- // post wait
- if (value >= 0 && value < work) tb_semaphore_post(impl->wait, work - value);
-}
-static tb_bool_t tb_aiop_push_sock(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && aice && aice->aico, tb_false);
-
- // the priority
- tb_size_t priority = tb_aice_impl_priority(aice);
- tb_assert_and_check_return_val(priority < tb_arrayn(impl->spak) && impl->spak[priority], tb_false);
-
- // this aico is killed? post to higher priority queue
- if (tb_aico_impl_is_killed((tb_aico_impl_t*)aice->aico)) priority = 0;
-
- // trace
- tb_trace_d("push: aico: %p, handle: %p, code: %lu, priority: %lu", aice->aico, tb_aico_sock(aice->aico), aice->code, priority);
-
- // enter
- tb_spinlock_enter(&impl->lock);
-
- // not full?
- if (!tb_queue_full(impl->spak[priority]))
- {
- // push aice to the spak queue
- tb_queue_put(impl->spak[priority], aice);
-
- // wait ok if be not acpt aice
- if (aice->code != TB_AICE_CODE_ACPT) ((tb_aiop_aico_t*)aice->aico)->wait_ok = 1;
- }
- else
- {
- // trace
- tb_trace_e("push: failed, the spak queue is full!");
- }
-
- // leave
- tb_spinlock_leave(&impl->lock);
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_aiop_push_acpt(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && aice, tb_false);
- tb_assert_and_check_return_val(aice->code == TB_AICE_CODE_ACPT, tb_false);
-
- // the aico
- tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico;
- tb_assert_and_check_return_val(aico && aico->base.handle, tb_false);
-
- // the priority
- tb_size_t priority = tb_aice_impl_priority(aice);
- tb_assert_and_check_return_val(priority < tb_arrayn(impl->spak) && impl->spak[priority], tb_false);
-
- // init the acpt aice
- tb_aice_t acpt_aice = *aice;
- acpt_aice.state = TB_STATE_OK;
-
- // done
- tb_size_t list_indx = 0;
- tb_size_t list_size = 0;
- tb_socket_ref_t list_sock[2048];
- tb_ipaddr_t list_addr[2048];
- tb_size_t list_maxn = tb_arrayn(list_sock);
- tb_socket_ref_t acpt = (tb_socket_ref_t)aico->base.handle;
- tb_queue_ref_t spak = impl->spak[priority];
- tb_socket_ref_t sock = tb_null;
- do
- {
- // accept it
- for (list_size = 0; list_size < list_maxn && (list_sock[list_size] = tb_socket_accept(acpt, list_addr + list_size)); list_size++) ;
-
- // enter
- tb_spinlock_enter(&impl->lock);
-
- // push some acpt aice
- for (list_indx = 0; list_indx < list_size && (sock = list_sock[list_indx]); list_indx++)
- {
- // init aico
- acpt_aice.u.acpt.aico = tb_aico_init(aico->base.aicp);
-
- // trace
- tb_trace_d("push: acpt[%p]: sock: %p, aico: %p", aico->base.handle, sock, acpt_aice.u.acpt.aico);
-
- // open aico and push the acpt aice if not full?
- if ( acpt_aice.u.acpt.aico
- && tb_aico_open_sock(acpt_aice.u.acpt.aico, sock)
- && !tb_queue_full(spak))
- {
- // save addr
- tb_ipaddr_copy(&acpt_aice.u.acpt.addr, list_addr + list_indx);
-
- // push to the spak queue
- tb_queue_put(spak, &acpt_aice);
- }
- else
- {
- // close the left sock
- tb_size_t i;
- for (i = list_indx; i < list_size; i++)
- {
- // close it
- if (list_sock[i]) tb_socket_exit(list_sock[i]);
- list_sock[i] = tb_null;
- }
-
- // exit aico
- if (acpt_aice.u.acpt.aico) tb_aico_exit(acpt_aice.u.acpt.aico);
- acpt_aice.u.acpt.aico = tb_null;
-
- // trace
- tb_trace_e("push: acpt failed!");
- break;
- }
- }
-
- // leave
- tb_spinlock_leave(&impl->lock);
-
- } while (list_indx == list_maxn);
-
- // ok
- return tb_true;
-}
-static tb_int_t tb_aiop_spak_loop(tb_cpointer_t priv)
-{
- // check
- tb_aiop_ptor_impl_t* impl = (tb_aiop_ptor_impl_t*)priv;
- tb_aicp_impl_t* aicp = impl? impl->base.aicp : tb_null;
-
- // done
- do
- {
- // check
- tb_assert_and_check_break(impl && impl->aiop && impl->list && impl->timer && impl->ltimer && aicp);
-
- // trace
- tb_trace_d("loop: init");
-
- // loop
- while (!tb_atomic_get(&aicp->kill))
- {
- // the delay
- tb_size_t delay = tb_timer_delay(impl->timer);
-
- // the ldelay
- tb_size_t ldelay = tb_ltimer_delay(impl->ltimer);
- tb_assert_and_check_break(ldelay != -1);
-
- // trace
- tb_trace_d("loop: wait: ..");
-
- // wait aioe
- tb_long_t real = tb_aiop_wait(impl->aiop, impl->list, impl->maxn, tb_min(delay, ldelay));
-
- // trace
- tb_trace_d("loop: wait: %ld", real);
-
- // spak ctime
- tb_cache_time_spak();
-
- // spak timer
- if (!tb_timer_spak(impl->timer)) break;
-
- // spak ltimer
- if (!tb_ltimer_spak(impl->ltimer)) break;
-
- // killed?
- tb_check_break(real >= 0);
-
- // error? out of range
- tb_assert_and_check_break(real <= impl->maxn);
-
- // timeout?
- tb_check_continue(real);
-
- // grow it if aioe is full
- if (real == impl->maxn)
- {
- // grow size
- impl->maxn += (aicp->maxn >> 4) + 16;
- if (impl->maxn > aicp->maxn) impl->maxn = aicp->maxn;
-
- // grow list
- impl->list = tb_ralloc(impl->list, impl->maxn * sizeof(tb_aioe_t));
- tb_assert_and_check_break(impl->list);
- }
-
- // walk aioe list
- tb_size_t i = 0;
- tb_bool_t end = tb_false;
- for (i = 0; i < real && !end; i++)
- {
- // the aioe
- tb_aioe_ref_t aioe = &impl->list[i];
- tb_assert_and_check_break_state(aioe, end, tb_true);
-
- // the aice
- tb_aice_ref_t aice = (tb_aice_ref_t)aioe->priv;
- tb_assert_and_check_break_state(aice, end, tb_true);
-
- // the aico
- tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico;
- tb_assert_and_check_break_state(aico, end, tb_true);
-
- // have wait?
- tb_check_continue(aice->code);
-
- // have been waited ok for the timer timeout/killed func? need not spak it repeatly
- tb_check_continue(!aico->wait_ok);
-
- // sock?
- if (aico->base.type == TB_AICO_TYPE_SOCK)
- {
- // push the acpt aice
- if (aice->code == TB_AICE_CODE_ACPT) end = tb_aiop_push_acpt(impl, aice)? tb_false : tb_true;
- // push the sock aice
- else end = tb_aiop_push_sock(impl, aice)? tb_false : tb_true;
- }
- else if (aico->base.type == TB_AICO_TYPE_FILE)
- {
- // poll file
- tb_aicp_file_poll(impl);
- }
- else tb_assert(0);
- }
-
- // end?
- tb_check_break(!end);
-
- // work it
- tb_aiop_spak_work(impl);
- }
-
- } while (0);
-
- // trace
- tb_trace_d("loop: exit");
-
- // kill
- tb_aicp_kill((tb_aicp_ref_t)aicp);
-
- // exit
- return 0;
-}
-static tb_void_t tb_aiop_spak_wait_timeout(tb_bool_t killed, tb_cpointer_t priv)
-{
- // the aico
- tb_aiop_aico_t* aico = (tb_aiop_aico_t*)priv;
- tb_assert_and_check_return(aico && aico->waiting);
-
- // the impl
- tb_aiop_ptor_impl_t* impl = aico->impl;
- tb_assert_and_check_return(impl && impl->aiop);
-
- // for sock
- if (aico->base.type == TB_AICO_TYPE_SOCK)
- {
- // check
- tb_assert_and_check_return(aico->aioo);
-
- // delo aioo
- tb_aiop_delo(impl->aiop, aico->aioo);
- aico->aioo = tb_null;
- }
-
- // have been waited ok for the spak loop? need not spak it repeatly
- tb_bool_t ok = tb_false;
- if (!aico->wait_ok)
- {
- // the priority
- tb_size_t priority = tb_aice_impl_priority(&aico->aice);
- tb_assert_and_check_return(priority < tb_arrayn(impl->spak) && impl->spak[priority]);
-
- // trace
- tb_trace_d("wait: timeout: code: %lu, priority: %lu, time: %lld", aico->aice.code, priority, tb_cache_time_mclock());
-
- // enter
- tb_spinlock_enter(&impl->lock);
-
- // spak aice
- if (!tb_queue_full(impl->spak[priority]))
- {
- // save state
- aico->aice.state = killed? TB_STATE_KILLED : TB_STATE_TIMEOUT;
-
- // put it
- tb_queue_put(impl->spak[priority], &aico->aice);
-
- // ok
- ok = tb_true;
- aico->wait_ok = 1;
- }
- else tb_assert(0);
-
- // leave
- tb_spinlock_leave(&impl->lock);
- }
-
- // work it
- if (ok) tb_aiop_spak_work(impl);
-}
-static tb_bool_t tb_aiop_spak_wait(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && impl->aiop && impl->ltimer && aice, tb_false);
-
- // the aico
- tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico;
- tb_assert_and_check_return_val(aico && aico->base.handle && !aico->task, tb_false);
-
- // the aioe code
- tb_size_t code = tb_aiop_aioe_code(aice);
- tb_assert_and_check_return_val(code != TB_AIOE_CODE_NONE, tb_false);
-
- // trace
- tb_trace_d("wait: aico: %p, code: %lu: time: %lld: ..", aico, aice->code, tb_cache_time_mclock());
-
- // done
- tb_bool_t ok = tb_false;
- tb_aice_t prev = aico->aice;
- do
- {
- // wait it
- aico->aice = *aice;
- aico->waiting = 1;
- aico->wait_ok = 0;
-
- // wait once if not accept
- if (aice->code != TB_AICE_CODE_ACPT) code |= TB_AIOE_CODE_ONESHOT;
-
- // using the edge triggered mode
- if (tb_aiop_have(impl->aiop, TB_AIOE_CODE_CLEAR))
- code |= TB_AIOE_CODE_CLEAR;
-
- // have aioo?
- if (!aico->aioo)
- {
- // addo wait
- if (!(aico->aioo = tb_aiop_addo(impl->aiop, aico->base.handle, code, &aico->aice))) break;
- }
- else
- {
- // sete wait
- if (!tb_aiop_sete(impl->aiop, aico->aioo, code, &aico->aice)) break;
- }
-
- // add timeout task
- tb_long_t timeout = tb_aico_impl_timeout_from_code((tb_aico_impl_t*)aico, aice->code);
- if (timeout >= 0)
- {
- // add it
- aico->task = tb_ltimer_task_init(impl->ltimer, timeout, tb_false, tb_aiop_spak_wait_timeout, aico);
- tb_assert_and_check_break(aico->task);
- aico->bltimer = 1;
- }
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed? restore it
- if (!ok)
- {
- // trace
- tb_trace_d("wait: aico: %p, code: %lu: failed", aico, aice->code);
-
- // restore it
- aico->aice = prev;
- aico->waiting = 0;
- }
-
- // ok?
- return ok;
-}
-static tb_long_t tb_aiop_spak_acpt(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && aice, -1);
- tb_assert_and_check_return_val(aice->code == TB_AICE_CODE_ACPT, -1);
-
- // the aico
- tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico;
- tb_assert_and_check_return_val(aico && aico->base.handle, -1);
- tb_assert_and_check_return_val(!aico->waiting, -1);
-
- // trace
- tb_trace_d("acpt[%p]: wait: ..", aico);
-
- // wait ok?
- if (tb_aiop_spak_wait(impl, aice)) return 0;
- // wait failed
- else aice->state = TB_STATE_FAILED;
-
- // trace
- tb_trace_d("acpt[%p]: wait: failed", aico);
-
- // reset wait
- aico->waiting = 0;
- aico->aice.code = TB_AICE_CODE_NONE;
-
- // ok
- return 1;
-}
-static tb_long_t tb_aiop_spak_conn(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && aice, -1);
- tb_assert_and_check_return_val(aice->code == TB_AICE_CODE_CONN, -1);
-
- // the aico
- tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico;
- tb_assert_and_check_return_val(aico && aico->base.handle, -1);
-
- // check address
- tb_assert(!tb_ipaddr_is_empty(&aice->u.conn.addr));
-
- // try to connect it
- tb_long_t ok = tb_socket_connect(aico->base.handle, &aice->u.conn.addr);
-
- // trace
- tb_trace_d("conn[%p]: %{ipaddr}: %ld", aico, &aice->u.conn.addr, ok);
-
- // no connected? wait it
- if (!ok)
- {
- // wait it
- if (!aico->waiting)
- {
- // wait ok?
- if (tb_aiop_spak_wait(impl, aice)) return 0;
- // wait failed
- else aice->state = TB_STATE_FAILED;
- }
- // closed
- else aice->state = TB_STATE_FAILED;
- }
-
- // save it
- aice->state = ok > 0? TB_STATE_OK : TB_STATE_FAILED;
-
- // reset wait
- aico->waiting = 0;
- aico->aice.code = TB_AICE_CODE_NONE;
-
- // ok
- return 1;
-}
-static tb_long_t tb_aiop_spak_recv(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && aice, -1);
- tb_assert_and_check_return_val(aice->code == TB_AICE_CODE_RECV, -1);
- tb_assert_and_check_return_val(aice->u.recv.data && aice->u.recv.size, -1);
-
- // the aico
- tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico;
- tb_assert_and_check_return_val(aico && aico->base.handle, -1);
-
- // try to recv it
- tb_size_t recv = 0;
- tb_long_t real = 0;
- while (recv < aice->u.recv.size)
- {
- // recv it
- real = tb_socket_recv(aico->base.handle, aice->u.recv.data + recv, aice->u.recv.size - recv);
-
- // save recv
- if (real > 0) recv += real;
- else break;
- }
-
- // trace
- tb_trace_d("recv[%p]: %lu", aico, recv);
-
- // no recv?
- if (!recv)
- {
- // wait it
- if (!real && !aico->waiting)
- {
- // wait ok?
- if (tb_aiop_spak_wait(impl, aice)) return 0;
- // wait failed
- else aice->state = TB_STATE_FAILED;
- }
- // closed
- else aice->state = TB_STATE_CLOSED;
- }
- else
- {
- // ok or closed?
- aice->state = TB_STATE_OK;
-
- // save the recv size
- aice->u.recv.real = recv;
- }
-
- // reset wait
- aico->waiting = 0;
- aico->aice.code = TB_AICE_CODE_NONE;
-
- // ok
- return 1;
-}
-static tb_long_t tb_aiop_spak_send(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && aice, -1);
- tb_assert_and_check_return_val(aice->code == TB_AICE_CODE_SEND, -1);
- tb_assert_and_check_return_val(aice->u.send.data && aice->u.send.size, -1);
-
- // the aico
- tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico;
- tb_assert_and_check_return_val(aico && aico->base.handle, -1);
-
- // try to send it
- tb_size_t send = 0;
- tb_long_t real = 0;
- while (send < aice->u.send.size)
- {
- // send it
- real = tb_socket_send(aico->base.handle, aice->u.send.data + send, aice->u.send.size - send);
-
- // save send
- if (real > 0) send += real;
- else break;
- }
-
- // trace
- tb_trace_d("send[%p]: %lu", aico, send);
-
- // no send?
- if (!send)
- {
- // wait it
- if (!real && !aico->waiting)
- {
- // wait ok?
- if (tb_aiop_spak_wait(impl, aice)) return 0;
- // wait failed
- else aice->state = TB_STATE_FAILED;
- }
- // closed
- else aice->state = TB_STATE_CLOSED;
- }
- else
- {
- // ok or closed?
- aice->state = TB_STATE_OK;
-
- // save the send size
- aice->u.send.real = send;
- }
-
- // reset wait
- aico->waiting = 0;
- aico->aice.code = TB_AICE_CODE_NONE;
-
- // ok
- return 1;
-}
-static tb_long_t tb_aiop_spak_urecv(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && aice, -1);
- tb_assert_and_check_return_val(aice->code == TB_AICE_CODE_URECV, -1);
- tb_assert_and_check_return_val(aice->u.urecv.data && aice->u.urecv.size, -1);
-
- // the aico
- tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico;
- tb_assert_and_check_return_val(aico && aico->base.handle, -1);
-
- // try to recv it
- tb_size_t recv = 0;
- tb_long_t real = 0;
- while (recv < aice->u.urecv.size)
- {
- // recv it
- real = tb_socket_urecv(aico->base.handle, &aice->u.urecv.addr, aice->u.urecv.data + recv, aice->u.urecv.size - recv);
-
- // save recv
- if (real > 0) recv += real;
- else break;
- }
-
- // no recv?
- if (!recv)
- {
- // wait it
- if (!real && !aico->waiting)
- {
- // wait ok?
- if (tb_aiop_spak_wait(impl, aice)) return 0;
- // wait failed
- else aice->state = TB_STATE_FAILED;
- }
- // closed
- else aice->state = TB_STATE_CLOSED;
- }
- else
- {
- // trace
- tb_trace_d("urecv[%p]: %{ipaddr}: %lu", aico, &aice->u.urecv.addr, recv);
-
- // ok or closed?
- aice->state = TB_STATE_OK;
-
- // save the recv size
- aice->u.urecv.real = recv;
- }
-
- // reset wait
- aico->waiting = 0;
- aico->aice.code = TB_AICE_CODE_NONE;
-
- // ok
- return 1;
-}
-static tb_long_t tb_aiop_spak_usend(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && aice, -1);
- tb_assert_and_check_return_val(aice->code == TB_AICE_CODE_USEND, -1);
- tb_assert_and_check_return_val(aice->u.usend.data && aice->u.usend.size, -1);
-
- // the aico
- tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico;
- tb_assert_and_check_return_val(aico && aico->base.handle, -1);
-
- // try to send it
- tb_size_t send = 0;
- tb_long_t real = 0;
- while (send < aice->u.usend.size)
- {
- // send it
- real = tb_socket_usend(aico->base.handle, &aice->u.usend.addr, aice->u.usend.data + send, aice->u.usend.size - send);
-
- // save send
- if (real > 0) send += real;
- else break;
- }
-
- // trace
- tb_trace_d("usend[%p]: %{ipaddr}: %lu", aico, &aice->u.usend.addr, send);
-
- // no send?
- if (!send)
- {
- // wait it
- if (!real && !aico->waiting)
- {
- // wait ok?
- if (tb_aiop_spak_wait(impl, aice)) return 0;
- // wait failed
- else aice->state = TB_STATE_FAILED;
- }
- // closed
- else aice->state = TB_STATE_CLOSED;
- }
- else
- {
- // ok or closed?
- aice->state = TB_STATE_OK;
-
- // save the send size
- aice->u.usend.real = send;
- }
-
- // reset wait
- aico->waiting = 0;
- aico->aice.code = TB_AICE_CODE_NONE;
-
- // ok
- return 1;
-}
-static tb_long_t tb_aiop_spak_recvv(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && aice, -1);
- tb_assert_and_check_return_val(aice->code == TB_AICE_CODE_RECVV, -1);
- tb_assert_and_check_return_val(aice->u.recvv.list && aice->u.recvv.size, -1);
-
- // the aico
- tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico;
- tb_assert_and_check_return_val(aico && aico->base.handle, -1);
-
- // recv it
- tb_long_t real = tb_socket_recvv(aico->base.handle, aice->u.recvv.list, aice->u.recvv.size);
-
- // trace
- tb_trace_d("recvv[%p]: %lu", aico, real);
-
- // ok?
- if (real > 0)
- {
- aice->u.recvv.real = real;
- aice->state = TB_STATE_OK;
- }
- // no recv?
- else if (!real && !aico->waiting)
- {
- // wait ok?
- if (tb_aiop_spak_wait(impl, aice)) return 0;
- // wait failed
- else aice->state = TB_STATE_FAILED;
- }
- // closed?
- else aice->state = TB_STATE_CLOSED;
-
- // reset wait
- aico->waiting = 0;
- aico->aice.code = TB_AICE_CODE_NONE;
-
- // ok
- return 1;
-}
-static tb_long_t tb_aiop_spak_sendv(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && aice, -1);
- tb_assert_and_check_return_val(aice->code == TB_AICE_CODE_SENDV, -1);
- tb_assert_and_check_return_val(aice->u.sendv.list && aice->u.sendv.size, -1);
-
- // the aico
- tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico;
- tb_assert_and_check_return_val(aico && aico->base.handle, -1);
-
- // send it
- tb_long_t real = tb_socket_sendv(aico->base.handle, aice->u.sendv.list, aice->u.sendv.size);
-
- // trace
- tb_trace_d("sendv[%p]: %lu", aico, real);
-
- // ok?
- if (real > 0)
- {
- aice->u.sendv.real = real;
- aice->state = TB_STATE_OK;
- }
- // no send?
- else if (!real && !aico->waiting)
- {
- // wait ok?
- if (tb_aiop_spak_wait(impl, aice)) return 0;
- // wait failed
- else aice->state = TB_STATE_FAILED;
- }
- // closed?
- else aice->state = TB_STATE_CLOSED;
-
- // reset wait
- aico->waiting = 0;
- aico->aice.code = TB_AICE_CODE_NONE;
-
- // ok
- return 1;
-}
-static tb_long_t tb_aiop_spak_urecvv(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && aice, -1);
- tb_assert_and_check_return_val(aice->code == TB_AICE_CODE_URECVV, -1);
- tb_assert_and_check_return_val(aice->u.urecvv.list && aice->u.urecvv.size, -1);
-
- // the aico
- tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico;
- tb_assert_and_check_return_val(aico && aico->base.handle, -1);
-
- // recv it
- tb_long_t real = tb_socket_urecvv(aico->base.handle, &aice->u.urecvv.addr, aice->u.urecvv.list, aice->u.urecvv.size);
-
- // trace
- tb_trace_d("urecvv[%p]: %{ipaddr}: %lu", aico, &aice->u.urecvv.addr, real);
-
- // ok?
- if (real > 0)
- {
- aice->u.urecvv.real = real;
- aice->state = TB_STATE_OK;
- }
- // no recv?
- else if (!real && !aico->waiting)
- {
- // wait ok?
- if (tb_aiop_spak_wait(impl, aice)) return 0;
- // wait failed
- else aice->state = TB_STATE_FAILED;
- }
- // closed?
- else aice->state = TB_STATE_CLOSED;
-
- // reset wait
- aico->waiting = 0;
- aico->aice.code = TB_AICE_CODE_NONE;
-
- // ok
- return 1;
-}
-static tb_long_t tb_aiop_spak_usendv(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && aice, -1);
- tb_assert_and_check_return_val(aice->code == TB_AICE_CODE_USENDV, -1);
- tb_assert_and_check_return_val(aice->u.usendv.list && aice->u.usendv.size, -1);
-
- // the aico
- tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico;
- tb_assert_and_check_return_val(aico && aico->base.handle, -1);
-
- // send it
- tb_long_t real = tb_socket_usendv(aico->base.handle, &aice->u.usendv.addr, aice->u.usendv.list, aice->u.usendv.size);
-
- // trace
- tb_trace_d("usendv[%p]: %{ipaddr}: %lu", aico, &aice->u.usendv.addr, real);
-
- // ok?
- if (real > 0)
- {
- aice->u.usendv.real = real;
- aice->state = TB_STATE_OK;
- }
- // no send?
- else if (!real && !aico->waiting)
- {
- // wait ok?
- if (tb_aiop_spak_wait(impl, aice)) return 0;
- // wait failed
- else aice->state = TB_STATE_FAILED;
- }
- // closed?
- else aice->state = TB_STATE_CLOSED;
-
- // reset wait
- aico->waiting = 0;
- aico->aice.code = TB_AICE_CODE_NONE;
-
- // ok
- return 1;
-}
-static tb_long_t tb_aiop_spak_sendf(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && aice, -1);
- tb_assert_and_check_return_val(aice->code == TB_AICE_CODE_SENDF, -1);
- tb_assert_and_check_return_val(aice->u.sendf.file && aice->u.sendf.size, -1);
-
- // the aico
- tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico;
- tb_assert_and_check_return_val(aico && aico->base.handle, -1);
-
- // try to send it
- tb_long_t real = 0;
- tb_hize_t send = 0;
- tb_hize_t seek = aice->u.sendf.seek;
- tb_hize_t size = aice->u.sendf.size;
- tb_handle_t file = aice->u.sendf.file;
- while (send < size)
- {
- // send it
- real = tb_socket_sendf(aico->base.handle, file, seek + send, size - send);
-
- // save send
- if (real > 0) send += real;
- else break;
- }
-
- // trace
- tb_trace_d("sendf[%p]: %llu", aico, send);
-
- // no send?
- if (!send)
- {
- // wait it
- if (!real && !aico->waiting)
- {
- // wait ok?
- if (tb_aiop_spak_wait(impl, aice)) return 0;
- // wait failed
- else aice->state = TB_STATE_FAILED;
- }
- // closed
- else aice->state = TB_STATE_CLOSED;
- }
- else
- {
- // ok or closed?
- aice->state = TB_STATE_OK;
-
- // save the send size
- aice->u.sendf.real = send;
- }
-
- // reset wait
- aico->waiting = 0;
- aico->aice.code = TB_AICE_CODE_NONE;
-
- // ok
- return 1;
-}
-static tb_void_t tb_aiop_spak_runtask_timeout(tb_bool_t killed, tb_cpointer_t priv)
-{
- // the aico
- tb_aiop_aico_t* aico = (tb_aiop_aico_t*)priv;
- tb_assert_and_check_return(aico && aico->waiting);
-
- // the impl
- tb_aiop_ptor_impl_t* impl = aico->impl;
- tb_assert_and_check_return(impl);
-
- // the priority
- tb_size_t priority = tb_aice_impl_priority(&aico->aice);
- tb_assert_and_check_return(priority < tb_arrayn(impl->spak) && impl->spak[priority]);
-
- // enter
- tb_spinlock_enter(&impl->lock);
-
- // trace
- tb_trace_d("runtask: timeout: code: %lu, priority: %lu, size: %lu", aico->aice.code, priority, tb_queue_size(impl->spak[priority]));
-
- // spak aice
- tb_bool_t ok = tb_false;
- if (!tb_queue_full(impl->spak[priority]))
- {
- // save state
- aico->aice.state = killed? TB_STATE_KILLED : TB_STATE_OK;
-
- // put it
- tb_queue_put(impl->spak[priority], &aico->aice);
-
- // ok
- ok = tb_true;
- }
- else tb_assert(0);
-
- // leave
- tb_spinlock_leave(&impl->lock);
-
- // work it
- if (ok) tb_aiop_spak_work(impl);
-}
-static tb_long_t tb_aiop_spak_runtask(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && impl->aiop && impl->ltimer && impl->timer && aice, -1);
- tb_assert_and_check_return_val(aice->code == TB_AICE_CODE_RUNTASK, -1);
- tb_assert_and_check_return_val(aice->u.runtask.when, -1);
-
- // the aico
- tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico;
- tb_assert_and_check_return_val(aico && !aico->task, -1);
-
- // now
- tb_hong_t now = tb_cache_time_mclock();
-
- // timeout?
- tb_long_t ok = -1;
- if (aice->u.runtask.when <= now)
- {
- // trace
- tb_trace_d("runtask: when: %llu, now: %lld: ok", aice->u.runtask.when, now);
-
- // ok
- aice->state = TB_STATE_OK;
- ok = 1;
- }
- else
- {
- // trace
- tb_trace_d("runtask: when: %llu, now: %lld: ..", aice->u.runtask.when, now);
-
- // wait it
- aico->aice = *aice;
- aico->waiting = 1;
-
- // add timeout task, is the higher precision timer?
- if (aico->base.handle)
- {
- // the top when
- tb_hize_t top = tb_timer_top(impl->timer);
-
- // add task
- aico->task = tb_timer_task_init_at(impl->timer, aice->u.runtask.when, 0, tb_false, tb_aiop_spak_runtask_timeout, aico);
- aico->bltimer = 0;
-
- // the top task is changed? spak aiop
- if (aico->task && aice->u.runtask.when < top)
- tb_aiop_spak(impl->aiop);
- }
- else
- {
- aico->task = tb_ltimer_task_init_at(impl->ltimer, aice->u.runtask.when, 0, tb_false, tb_aiop_spak_runtask_timeout, aico);
- aico->bltimer = 1;
- }
-
- // wait
- ok = 0;
- }
-
- // ok
- return ok;
-}
-static tb_long_t tb_aiop_spak_clos(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && impl->aiop && impl->ltimer && impl->timer && aice, -1);
- tb_assert_and_check_return_val(aice->code == TB_AICE_CODE_CLOS, -1);
-
- // the aico
- tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico;
- tb_assert_and_check_return_val(aico, -1);
-
- // trace
- tb_trace_d("clos: aico: %p, code: %u: %s", aico, aice->code, tb_state_cstr(tb_atomic_get(&aico->base.state)));
-
- // exit the timer task
- if (aico->task)
- {
- if (aico->bltimer) tb_ltimer_task_exit(impl->ltimer, aico->task);
- else tb_timer_task_exit(impl->timer, aico->task);
- aico->bltimer = 0;
- }
- aico->task = tb_null;
-
- // exit the sock
- if (aico->base.type == TB_AICO_TYPE_SOCK)
- {
- // remove aioo
- if (aico->aioo) tb_aiop_delo(impl->aiop, aico->aioo);
- aico->aioo = tb_null;
-
- // close the socket handle
- if (aico->base.handle) tb_socket_exit((tb_socket_ref_t)aico->base.handle);
- aico->base.handle = tb_null;
- }
- // exit file
- else if (aico->base.type == TB_AICO_TYPE_FILE)
- {
- // exit the file handle
- if (aico->base.handle) tb_file_exit((tb_file_ref_t)aico->base.handle);
- aico->base.handle = tb_null;
- }
-
- // clear waiting state
- aico->waiting = 0;
- aico->wait_ok = 0;
- aico->aice.code = TB_AICE_CODE_NONE;
-
- // clear type
- aico->base.type = TB_AICO_TYPE_NONE;
-
- // clear timeout
- tb_size_t i = 0;
- tb_size_t n = tb_arrayn(aico->base.timeout);
- for (i = 0; i < n; i++) aico->base.timeout[i] = -1;
-
- // closed
- tb_atomic_set(&aico->base.state, TB_STATE_CLOSED);
-
- // ok
- aice->state = TB_STATE_OK;
- return 1;
-}
-static tb_long_t tb_aiop_spak_done(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && impl->timer && impl->ltimer && aice, -1);
-
- // the aico
- tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico;
- tb_assert_and_check_return_val(aico, -1);
-
- // remove task
- if (aico->task)
- {
- if (aico->bltimer) tb_ltimer_task_exit(impl->ltimer, aico->task);
- else tb_timer_task_exit(impl->timer, aico->task);
- aico->bltimer = 0;
- }
- aico->task = tb_null;
-
- // spak the killed aice if not closing
- if (tb_aico_impl_is_killed(&aico->base) && aice->code != TB_AICE_CODE_CLOS)
- {
- // clear waiting state if not accept
- if (aice->code != TB_AICE_CODE_ACPT)
- {
- aico->waiting = 0;
- aico->aice.code = TB_AICE_CODE_NONE;
- }
-
- // save state
- aice->state = TB_STATE_KILLED;
-
- // trace
- tb_trace_d("spak: aico: %p, code: %u: killed", aico, aice->code);
-
- // ok
- return 1;
- }
-
- // no pending? spak it directly
- if (aice->state != TB_STATE_PENDING)
- {
- // clear waiting state if not accept
- if (aice->code != TB_AICE_CODE_ACPT)
- {
- aico->waiting = 0;
- aico->aice.code = TB_AICE_CODE_NONE;
- }
-
- // ok
- return 1;
- }
-
- // init spak
- static tb_long_t (*s_spak[])(tb_aiop_ptor_impl_t* , tb_aice_ref_t) =
- {
- tb_null
-
- , tb_aiop_spak_acpt
- , tb_aiop_spak_conn
- , tb_aiop_spak_recv
- , tb_aiop_spak_send
- , tb_aiop_spak_urecv
- , tb_aiop_spak_usend
- , tb_aiop_spak_recvv
- , tb_aiop_spak_sendv
- , tb_aiop_spak_urecvv
- , tb_aiop_spak_usendv
- , tb_aiop_spak_sendf
-
- , tb_aicp_file_spak_read
- , tb_aicp_file_spak_writ
- , tb_aicp_file_spak_readv
- , tb_aicp_file_spak_writv
- , tb_aicp_file_spak_fsync
-
- , tb_aiop_spak_runtask
- , tb_null
- };
- tb_assert_and_check_return_val(aice->code && aice->code < tb_arrayn(s_spak) && s_spak[aice->code], -1);
-
- // done spak
- return s_spak[aice->code](impl, aice);
-}
-static tb_void_t tb_aiop_spak_klist(tb_aiop_ptor_impl_t* impl)
-{
- // check
- tb_assert_and_check_return(impl && impl->klist);
-
- // enter
- tb_spinlock_enter(&impl->klock);
-
- // kill it if exists the killing aico
- if (tb_vector_size(impl->klist))
- {
- // kill all
- tb_for_all_if (tb_aico_impl_t*, aico, impl->klist, aico)
- {
- // the aiop aico
- tb_aiop_aico_t* aiop_aico = (tb_aiop_aico_t*)aico;
-
- // sock?
- if (aico->type == TB_AICO_TYPE_SOCK)
- {
- // add it first if do not exists timeout task
- if (!aiop_aico->task)
- {
- aiop_aico->task = tb_ltimer_task_init(impl->ltimer, 10000, tb_false, tb_aiop_spak_wait_timeout, aico);
- aiop_aico->bltimer = 1;
- }
-
- // kill the task
- if (aiop_aico->task)
- {
- // kill task
- if (aiop_aico->bltimer) tb_ltimer_task_kill(impl->ltimer, aiop_aico->task);
- else tb_timer_task_kill(impl->timer, aiop_aico->task);
- }
- }
- else if (aico->type == TB_AICO_TYPE_FILE)
- {
- // kill file
- tb_aicp_file_kilo(impl, aico);
- }
-
- // trace
- tb_trace_d("kill: aico: %p, type: %u: ok", aico, aico->type);
- }
- }
-
- // clear the killing aico list
- tb_vector_clear(impl->klist);
-
- // leave
- tb_spinlock_leave(&impl->klock);
-
- /* the aiop will wait long time if the lastest task wait period is too long
- * so spak the aiop manually for spak the timer
- */
- tb_aiop_spak(impl->aiop);
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static tb_bool_t tb_aiop_ptor_addo(tb_aicp_ptor_impl_t* ptor, tb_aico_impl_t* aico)
-{
- // check
- tb_aiop_ptor_impl_t* impl = (tb_aiop_ptor_impl_t*)ptor;
- tb_assert_and_check_return_val(impl && impl->aiop && aico, tb_false);
-
- // the aiop aico
- tb_aiop_aico_t* aiop_aico = (tb_aiop_aico_t*)aico;
-
- // init impl
- aiop_aico->impl = impl;
-
- // done
- tb_bool_t ok = tb_false;
- switch (aico->type)
- {
- case TB_AICO_TYPE_SOCK:
- {
- // check
- tb_assert_and_check_break(aico->handle);
-
- // ok
- ok = tb_true;
- }
- break;
- case TB_AICO_TYPE_FILE:
- {
- // check
- tb_assert_and_check_break(aico->handle);
-
- // file: addo
- ok = tb_aicp_file_addo(impl, aico);
- }
- break;
- case TB_AICO_TYPE_TASK:
- {
- // ok
- ok = tb_true;
- }
- break;
- default:
- break;
- }
-
- // ok?
- return ok;
-}
-static tb_void_t tb_aiop_ptor_kilo(tb_aicp_ptor_impl_t* ptor, tb_aico_impl_t* aico)
-{
- // check
- tb_aiop_ptor_impl_t* impl = (tb_aiop_ptor_impl_t*)ptor;
- tb_assert_and_check_return(impl && impl->klist && aico);
-
- // trace
- tb_trace_d("kill: aico: %p, type: %u: ..", aico, aico->type);
-
- // append the killing aico
- tb_spinlock_enter(&impl->klock);
- tb_vector_insert_tail(impl->klist, aico);
- tb_spinlock_leave(&impl->klock);
-
- // work it
- tb_aiop_spak_work(impl);
-}
-static tb_bool_t tb_aiop_ptor_post(tb_aicp_ptor_impl_t* ptor, tb_aice_ref_t aice)
-{
- // check
- tb_aiop_ptor_impl_t* impl = (tb_aiop_ptor_impl_t*)ptor;
- tb_assert_and_check_return_val(impl && aice && aice->aico, tb_false);
-
- // optimizate to spak the clos aice
- if (aice->code == TB_AICE_CODE_CLOS)
- {
- // spak the clos
- tb_aice_t resp = *aice;
- if (tb_aiop_spak_clos(impl, &resp) <= 0) return tb_false;
-
- // done the aice response function
- aice->func(&resp);
-
- // post ok
- return tb_true;
- }
-
- // the priority
- tb_size_t priority = tb_aice_impl_priority(aice);
- tb_assert_and_check_return_val(priority < tb_arrayn(impl->spak) && impl->spak[priority], tb_false);
-
- // done
- tb_bool_t ok = tb_true;
- tb_aico_impl_t* aico = (tb_aico_impl_t*)aice->aico;
- switch (aico->type)
- {
- case TB_AICO_TYPE_SOCK:
- case TB_AICO_TYPE_TASK:
- {
- // enter
- tb_spinlock_enter(&impl->lock);
-
- // post aice
- if (!tb_queue_full(impl->spak[priority]))
- {
- // put
- tb_queue_put(impl->spak[priority], aice);
-
- // trace
- tb_trace_d("post: code: %lu, priority: %lu, size: %lu", aice->code, priority, tb_queue_size(impl->spak[priority]));
- }
- else
- {
- // failed
- ok = tb_false;
-
- // trace
- tb_trace_e("post: code: %lu, priority: %lu, size: %lu: failed", aice->code, priority, tb_queue_size(impl->spak[priority]));
- }
-
- // leave
- tb_spinlock_leave(&impl->lock);
- }
- break;
- case TB_AICO_TYPE_FILE:
- {
- // post file
- ok = tb_aicp_file_post(impl, aice);
- }
- break;
- default:
- ok = tb_false;
- break;
- }
-
- // work it
- if (ok) tb_aiop_spak_work(impl);
-
- // ok?
- return ok;
-}
-static tb_void_t tb_aiop_ptor_kill(tb_aicp_ptor_impl_t* ptor)
-{
- // check
- tb_aiop_ptor_impl_t* impl = (tb_aiop_ptor_impl_t*)ptor;
- tb_assert_and_check_return(impl && impl->timer && impl->ltimer && impl->aiop);
-
- // trace
- tb_trace_d("kill: ..");
-
- // kill aiop
- tb_aiop_kill(impl->aiop);
-
- // kill file
- tb_aicp_file_kill(impl);
-
- // work it
- tb_aiop_spak_work(impl);
-}
-static tb_void_t tb_aiop_ptor_exit(tb_aicp_ptor_impl_t* ptor)
-{
- // check
- tb_aiop_ptor_impl_t* impl = (tb_aiop_ptor_impl_t*)ptor;
- tb_assert_and_check_return(impl);
-
- // trace
- tb_trace_d("exit");
-
- // exit file
- tb_aicp_file_exit(impl);
-
- // exit loop
- if (impl->loop)
- {
- tb_long_t wait = 0;
- if ((wait = tb_thread_wait(impl->loop, 5000, tb_null)) <= 0)
- {
- // trace
- tb_trace_e("loop[%p]: wait failed: %ld!", impl->loop, wait);
- }
- tb_thread_exit(impl->loop);
- impl->loop = tb_null;
- }
-
- // exit spak
- tb_spinlock_enter(&impl->lock);
- if (impl->spak[0]) tb_queue_exit(impl->spak[0]);
- if (impl->spak[1]) tb_queue_exit(impl->spak[1]);
- impl->spak[0] = tb_null;
- impl->spak[1] = tb_null;
- tb_spinlock_leave(&impl->lock);
-
- // exit kill
- tb_spinlock_enter(&impl->klock);
- if (impl->klist) tb_vector_exit(impl->klist);
- impl->klist = tb_null;
- tb_spinlock_leave(&impl->klock);
-
- // exit aiop
- if (impl->aiop) tb_aiop_exit(impl->aiop);
- impl->aiop = tb_null;
-
- // exit list
- if (impl->list) tb_free(impl->list);
- impl->list = tb_null;
-
- // exit wait
- if (impl->wait) tb_semaphore_exit(impl->wait);
- impl->wait = tb_null;
-
- // exit timer
- if (impl->timer) tb_timer_exit(impl->timer);
- impl->timer = tb_null;
-
- // exit ltimer
- if (impl->ltimer) tb_ltimer_exit(impl->ltimer);
- impl->ltimer = tb_null;
-
- // exit lock
- tb_spinlock_exit(&impl->lock);
-
- // exit it
- tb_free(impl);
-}
-static tb_long_t tb_aiop_ptor_spak(tb_aicp_ptor_impl_t* ptor, tb_handle_t loop, tb_aice_ref_t resp, tb_long_t timeout)
-{
- // check
- tb_aiop_ptor_impl_t* impl = (tb_aiop_ptor_impl_t*)ptor;
- tb_aicp_impl_t* aicp = impl? impl->base.aicp : tb_null;
- tb_assert_and_check_return_val(impl && impl->wait && aicp && resp, -1);
-
- // spak the killing list
- tb_aiop_spak_klist(impl);
-
- // enter
- tb_spinlock_enter(&impl->lock);
-
- // done
- tb_long_t ok = -1;
- tb_bool_t null = tb_false;
- do
- {
- // check
- tb_assert_and_check_break(impl->spak[0] && impl->spak[1]);
-
- // clear ok
- ok = 0;
-
- // spak aice from the higher priority spak first
- if (!(null = tb_queue_null(impl->spak[0])))
- {
- // get resp
- tb_aice_ref_t aice = tb_queue_get(impl->spak[0]);
- if (aice)
- {
- // save resp
- *resp = *aice;
-
- // trace
- tb_trace_d("spak[%u]: code: %lu, priority: 0, size: %lu", (tb_uint16_t)tb_thread_self(), aice->code, tb_queue_size(impl->spak[0]));
-
- // pop it
- tb_queue_pop(impl->spak[0]);
-
- // ok
- ok = 1;
- }
- }
-
- // no aice? spak aice from the lower priority spak next
- if (!ok && !(null = tb_queue_null(impl->spak[1])))
- {
- // get resp
- tb_aice_ref_t aice = tb_queue_get(impl->spak[1]);
- if (aice)
- {
- // save resp
- *resp = *aice;
-
- // trace
- tb_trace_d("spak[%u]: code: %lu, priority: 1, size: %lu", (tb_uint16_t)tb_thread_self(), aice->code, tb_queue_size(impl->spak[1]));
-
- // pop it
- tb_queue_pop(impl->spak[1]);
-
- // ok
- ok = 1;
- }
- }
-
- } while (0);
-
- // leave
- tb_spinlock_leave(&impl->lock);
-
- // done it
- if (ok) ok = tb_aiop_spak_done(impl, resp);
-
- // null? wait it
- tb_check_return_val(!ok && null, ok);
-
- // killed? break it
- tb_check_return_val(!tb_atomic_get(&aicp->kill), -1);
-
- // trace
- tb_trace_d("wait[%u]: ..", (tb_uint16_t)tb_thread_self());
-
- // wait some time
- if (tb_semaphore_wait(impl->wait, timeout) < 0) return -1;
-
- // timeout
- return 0;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * file implementation
- */
-#include "aicp_file.c"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-static tb_aicp_ptor_impl_t* tb_aiop_ptor_init(tb_aicp_impl_t* aicp)
-{
- // check
- tb_assert_and_check_return_val(aicp && aicp->maxn, tb_null);
-
- // done
- tb_bool_t ok = tb_false;
- tb_aiop_ptor_impl_t* impl = tb_null;
- do
- {
- // make ptor
- impl = tb_malloc0_type(tb_aiop_ptor_impl_t);
- tb_assert_and_check_break(impl);
-
- // init base
- impl->base.aicp = aicp;
- impl->base.step = sizeof(tb_aiop_aico_t);
- impl->base.kill = tb_aiop_ptor_kill;
- impl->base.exit = tb_aiop_ptor_exit;
- impl->base.addo = tb_aiop_ptor_addo;
- impl->base.kilo = tb_aiop_ptor_kilo;
- impl->base.post = tb_aiop_ptor_post;
- impl->base.loop_spak = tb_aiop_ptor_spak;
-
- // init lock
- if (!tb_spinlock_init(&impl->lock)) break;
-
- // init wait
- impl->wait = tb_semaphore_init(0);
- tb_assert_and_check_break(impl->wait);
-
- // init aiop
- impl->aiop = tb_aiop_init(aicp->maxn);
- tb_assert_and_check_break(impl->aiop);
-
- // check
- tb_assert_and_check_break(tb_aiop_have(impl->aiop, TB_AIOE_CODE_EALL | TB_AIOE_CODE_ONESHOT));
-
- // init spak
- impl->spak[0] = tb_queue_init((aicp->maxn >> 4) + 16, tb_element_mem(sizeof(tb_aice_t), tb_null, tb_null));
- impl->spak[1] = tb_queue_init((aicp->maxn >> 4) + 16, tb_element_mem(sizeof(tb_aice_t), tb_null, tb_null));
- tb_assert_and_check_break(impl->spak[0] && impl->spak[1]);
-
- // init file
- if (!tb_aicp_file_init(impl)) break;
-
- // init list
- impl->maxn = (aicp->maxn >> 4) + 16;
- impl->list = tb_nalloc0(impl->maxn, sizeof(tb_aioe_t));
- tb_assert_and_check_break(impl->list);
-
- // init timer and using cache time
- impl->timer = tb_timer_init(aicp->maxn >> 8, tb_true);
- tb_assert_and_check_break(impl->timer);
-
- // init ltimer and using cache time
- impl->ltimer = tb_ltimer_init(aicp->maxn >> 8, TB_LTIMER_TICK_S, tb_true);
- tb_assert_and_check_break(impl->ltimer);
-
- // init the killing list lock
- if (!tb_spinlock_init(&impl->klock)) break;
-
- // init the killing aico list
- impl->klist = tb_vector_init((aicp->maxn >> 6) + 16, tb_element_ptr(tb_null, tb_null));
- tb_assert_and_check_break(impl->klist);
-
- // register lock profiler
-#ifdef TB_LOCK_PROFILER_ENABLE
- tb_lock_profiler_register(tb_lock_profiler(), (tb_pointer_t)&impl->lock, "aicp_aiop");
-#endif
-
- // init loop
- impl->loop = tb_thread_init(tb_null, tb_aiop_spak_loop, impl, 0);
- tb_assert_and_check_break(impl->loop);
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (impl) tb_aiop_ptor_exit((tb_aicp_ptor_impl_t*)impl);
- return tb_null;
- }
-
- // ok?
- return (tb_aicp_ptor_impl_t*)impl;
-}
-
diff --git a/core/src/tbox/src/tbox/asio/deprecated/impl/aicp_file.c b/core/src/tbox/src/tbox/asio/deprecated/impl/aicp_file.c
deleted file mode 100644
index c8c60df5f..000000000
--- a/core/src/tbox/src/tbox/asio/deprecated/impl/aicp_file.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file aicp_file.c
- * @ingroup platform
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static tb_bool_t tb_aicp_file_init(tb_aiop_ptor_impl_t* impl)
-{
- return tb_true;
-}
-static tb_void_t tb_aicp_file_exit(tb_aiop_ptor_impl_t* impl)
-{
-}
-static tb_bool_t tb_aicp_file_addo(tb_aiop_ptor_impl_t* impl, tb_aico_impl_t* aico)
-{
- return tb_true;
-}
-static tb_void_t tb_aicp_file_kilo(tb_aiop_ptor_impl_t* impl, tb_aico_impl_t* aico)
-{
- // check
- tb_file_ref_t file = tb_aico_file((tb_aico_ref_t)aico);
- tb_assert_and_check_return(file);
-
- // kill it
- tb_file_exit(file);
-}
-static tb_bool_t tb_aicp_file_post(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && aice, tb_false);
-
- // the priority
- tb_size_t priority = tb_aice_impl_priority(aice);
- tb_assert_and_check_return_val(priority < tb_arrayn(impl->spak) && impl->spak[priority], tb_false);
-
- // enter
- tb_spinlock_enter(&impl->lock);
-
- // post aice
- tb_bool_t ok = tb_true;
- if (!tb_queue_full(impl->spak[priority]))
- {
- // put
- tb_queue_put(impl->spak[priority], aice);
-
- // trace
- tb_trace_d("post: code: %lu, priority: %lu, size: %lu", aice->code, priority, tb_queue_size(impl->spak[priority]));
- }
- else
- {
- // failed
- ok = tb_false;
-
- // assert
- tb_assert(0);
- }
-
- // leave
- tb_spinlock_leave(&impl->lock);
-
- // ok?
- return ok;
-}
-static tb_long_t tb_aicp_file_spak_read(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && aice && aice->code == TB_AICE_CODE_READ, -1);
- tb_assert_and_check_return_val(aice->u.read.data && aice->u.read.size, -1);
-
- // the file
- tb_file_ref_t file = tb_aico_file(aice->aico);
- tb_assert_and_check_return_val(file, -1);
-
- // read it from the given offset
- tb_long_t real = tb_file_pread(file, aice->u.read.data, aice->u.read.size, aice->u.read.seek);
-
- // trace
- tb_trace_d("read[%p]: %ld", file, real);
-
- // ok?
- if (real > 0)
- {
- aice->u.read.real = real;
- aice->state = TB_STATE_OK;
- }
- // closed?
- else if (!real) aice->state = TB_STATE_CLOSED;
- // failed?
- else aice->state = TB_STATE_FAILED;
-
- // ok?
- return 1;
-}
-static tb_long_t tb_aicp_file_spak_writ(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && aice && aice->code == TB_AICE_CODE_WRIT, -1);
- tb_assert_and_check_return_val(aice->u.writ.data && aice->u.writ.size, -1);
-
- // the file
- tb_file_ref_t file = tb_aico_file(aice->aico);
- tb_assert_and_check_return_val(file, -1);
-
- // writ it from the given offset
- tb_long_t real = tb_file_pwrit(file, aice->u.writ.data, aice->u.read.size, aice->u.writ.seek);
-
- // trace
- tb_trace_d("writ[%p]: %ld", file, real);
-
- // ok?
- if (real > 0)
- {
- aice->u.writ.real = real;
- aice->state = TB_STATE_OK;
- }
- // closed?
- else if (!real) aice->state = TB_STATE_CLOSED;
- // failed?
- else aice->state = TB_STATE_FAILED;
-
- // ok?
- return 1;
-}
-static tb_long_t tb_aicp_file_spak_readv(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && aice && aice->code == TB_AICE_CODE_READV, -1);
- tb_assert_and_check_return_val(aice->u.readv.list && aice->u.readv.size, -1);
-
- // the file
- tb_file_ref_t file = tb_aico_file(aice->aico);
- tb_assert_and_check_return_val(file, -1);
-
- // read it from the given offset
- tb_long_t real = tb_file_preadv(file, aice->u.readv.list, aice->u.readv.size, aice->u.readv.seek);
-
- // trace
- tb_trace_d("readv[%p]: %ld", file, real);
-
- // ok?
- if (real > 0)
- {
- aice->u.readv.real = real;
- aice->state = TB_STATE_OK;
- }
- // closed?
- else if (!real) aice->state = TB_STATE_CLOSED;
- // failed?
- else aice->state = TB_STATE_FAILED;
-
- // ok?
- return 1;
-}
-static tb_long_t tb_aicp_file_spak_writv(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && aice && aice->code == TB_AICE_CODE_WRITV, -1);
- tb_assert_and_check_return_val(aice->u.writv.list && aice->u.writv.size, -1);
-
- // the file
- tb_file_ref_t file = tb_aico_file(aice->aico);
- tb_assert_and_check_return_val(file, -1);
-
- // read it from the given offset
- tb_long_t real = tb_file_pwritv(file, aice->u.writv.list, aice->u.writv.size, aice->u.writv.seek);
-
- // trace
- tb_trace_d("writv[%p]: %ld", file, real);
-
- // ok?
- if (real > 0)
- {
- aice->u.writv.real = real;
- aice->state = TB_STATE_OK;
- }
- // closed?
- else if (!real) aice->state = TB_STATE_CLOSED;
- // failed?
- else aice->state = TB_STATE_FAILED;
-
- // ok?
- return 1;
-}
-static tb_long_t tb_aicp_file_spak_fsync(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(impl && aice && aice->code == TB_AICE_CODE_FSYNC, -1);
-
- // the file
- tb_file_ref_t file = tb_aico_file(aice->aico);
- tb_assert_and_check_return_val(file, -1);
-
- // done sync
- tb_bool_t ok = tb_file_sync(file);
-
- // trace
- tb_trace_d("fsync[%p]: %s", file, ok? "ok" : "no");
-
- // ok?
- aice->state = ok? TB_STATE_OK : TB_STATE_FAILED;
-
- // ok?
- return 1;
-}
-static tb_void_t tb_aicp_file_kill(tb_aiop_ptor_impl_t* impl)
-{
-}
-static tb_void_t tb_aicp_file_poll(tb_aiop_ptor_impl_t* impl)
-{
-}
-
diff --git a/core/src/tbox/src/tbox/asio/deprecated/impl/prefix.h b/core/src/tbox/src/tbox/asio/deprecated/impl/prefix.h
deleted file mode 100644
index 35bc9ad22..000000000
--- a/core/src/tbox/src/tbox/asio/deprecated/impl/prefix.h
+++ /dev/null
@@ -1,323 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file prefix.h
- *
- */
-#ifndef TB_ASIO_IMPL_PREFIX_H
-#define TB_ASIO_IMPL_PREFIX_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "../prefix.h"
-#include "../aicp.h"
-#include "../aiop.h"
-#include "../../../memory/memory.h"
-#include "../../../platform/platform.h"
-#include "../../../algorithm/algorithm.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the aioo impl type
-typedef struct __tb_aioo_impl_t
-{
- // the code
- tb_size_t code;
-
- // the priv
- tb_cpointer_t priv;
-
- // the socket
- tb_socket_ref_t sock;
-
-}tb_aioo_impl_t;
-
-// the aico impl type
-typedef struct __tb_aico_impl_t
-{
- // the aicp
- tb_aicp_ref_t aicp;
-
- // the type
- tb_size_t type;
-
- // the handle
- tb_handle_t handle;
-
- /*! the state
- *
- * <pre>
- * TB_STATE_CLOSED
- * TB_STATE_OPENED
- * TB_STATE_KILLED
- * TB_STATE_KILLING
- * TB_STATE_PENDING
- * </pre>
- */
- tb_atomic_t state;
-
- // the timeout for aice
- tb_atomic_t timeout[TB_AICO_TIMEOUT_MAXN];
-
-#ifdef __tb_debug__
- // the func
- tb_char_t const* func;
-
- // the file
- tb_char_t const* file;
-
- // the line
- tb_size_t line;
-#endif
-
-}tb_aico_impl_t;
-
-// the aicp proactor impl type
-struct __tb_aicp_impl_t;
-typedef struct __tb_aicp_ptor_impl_t
-{
- // aicp
- struct __tb_aicp_impl_t* aicp;
-
- // the aico step
- tb_size_t step;
-
- // kill
- tb_void_t (*kill)(struct __tb_aicp_ptor_impl_t* ptor);
-
- // exit
- tb_void_t (*exit)(struct __tb_aicp_ptor_impl_t* ptor);
-
- // addo
- tb_bool_t (*addo)(struct __tb_aicp_ptor_impl_t* ptor, tb_aico_impl_t* aico);
-
- // kilo
- tb_void_t (*kilo)(struct __tb_aicp_ptor_impl_t* ptor, tb_aico_impl_t* aico);
-
- // post
- tb_bool_t (*post)(struct __tb_aicp_ptor_impl_t* ptor, tb_aice_ref_t aice);
-
- // loop: init
- tb_handle_t (*loop_init)(struct __tb_aicp_ptor_impl_t* ptor);
-
- // loop: exit
- tb_void_t (*loop_exit)(struct __tb_aicp_ptor_impl_t* ptor, tb_handle_t loop);
-
- // loop: spak
- tb_long_t (*loop_spak)(struct __tb_aicp_ptor_impl_t* ptor, tb_handle_t loop, tb_aice_ref_t resp, tb_long_t timeout);
-
-}tb_aicp_ptor_impl_t;
-
-// the aiop reactor impl type
-struct __tb_aiop_impl_t;
-typedef struct __tb_aiop_rtor_impl_t
-{
- // aiop
- struct __tb_aiop_impl_t* aiop;
-
- // the supported aioe code
- tb_size_t code;
-
- // exit
- tb_void_t (*exit)(struct __tb_aiop_rtor_impl_t* rtor);
-
- // cler
- tb_void_t (*cler)(struct __tb_aiop_rtor_impl_t* rtor);
-
- // addo
- tb_bool_t (*addo)(struct __tb_aiop_rtor_impl_t* rtor, tb_aioo_impl_t const* aioo);
-
- // delo
- tb_bool_t (*delo)(struct __tb_aiop_rtor_impl_t* rtor, tb_aioo_impl_t const* aioo);
-
- // post
- tb_bool_t (*post)(struct __tb_aiop_rtor_impl_t* rtor, tb_aioe_ref_t aioe);
-
- // wait
- tb_long_t (*wait)(struct __tb_aiop_rtor_impl_t* rtor, tb_aioe_ref_t list, tb_size_t maxn, tb_long_t timeout);
-
-}tb_aiop_rtor_impl_t;
-
-// the aicp impl type
-typedef struct __tb_aicp_impl_t
-{
- // the object maxn
- tb_size_t maxn;
-
- // the ptor
- tb_aicp_ptor_impl_t* ptor;
-
- // the worker size
- tb_atomic_t work;
-
- // the pool
- tb_fixed_pool_ref_t pool;
-
- // the pool lock
- tb_spinlock_t lock;
-
- // kill it?
- tb_atomic_t kill;
-
- // killall it?
- tb_atomic_t kill_all;
-
-}tb_aicp_impl_t;
-
-// the aiop impl type
-typedef struct __tb_aiop_impl_t
-{
- // the aioo maxn
- tb_size_t maxn;
-
- // the aioo pool
- tb_fixed_pool_ref_t pool;
-
- // the pool lock
- tb_spinlock_t lock;
-
- // the reactor
- tb_aiop_rtor_impl_t* rtor;
-
- // the spak
- tb_socket_ref_t spak[2];
-
-}tb_aiop_impl_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/* init aicp proactor
- *
- * @param aicp the aicp impl
- *
- * @return the aicp proactor impl
- */
-tb_aicp_ptor_impl_t* tb_aicp_ptor_impl_init(tb_aicp_impl_t* aicp);
-
-/* init aiop reactor
- *
- * @param aiop the aiop impl
- *
- * @return the aiop reactor impl
- */
-tb_aiop_rtor_impl_t* tb_aiop_rtor_impl_init(tb_aiop_impl_t* aiop);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * inlines
- */
-static __tb_inline__ tb_bool_t tb_aico_impl_is_killed(tb_aico_impl_t* aico)
-{
- // check
- tb_assert_and_check_return_val(aico, tb_false);
-
- // the state
- tb_size_t state = tb_atomic_get(&aico->state);
-
- // killing or exiting or killed?
- return (state == TB_STATE_KILLING) || (state == TB_STATE_KILLED);
-}
-static __tb_inline__ tb_size_t tb_aice_impl_priority(tb_aice_ref_t aice)
-{
- // the priorities
- static tb_size_t s_priorities[] =
- {
- 1
-
- , 1
- , 0 // acpt
- , 0 // conn
- , 1
- , 1
- , 1
- , 1
- , 1
- , 1
- , 1
- , 1
- , 1
-
- , 1
- , 1
- , 1
- , 1
- , 1
-
- , 0 // task
- , 0 // clos
- };
- tb_assert_and_check_return_val(aice->code && aice->code < tb_arrayn(s_priorities), 1);
-
- // the priority
- return s_priorities[aice->code];
-}
-static __tb_inline__ tb_long_t tb_aico_impl_timeout_from_code(tb_aico_impl_t* aico, tb_size_t code)
-{
- // init the timeout type
- static tb_size_t type[] =
- {
- -1
-
- , -1
- , TB_AICO_TIMEOUT_CONN
- , TB_AICO_TIMEOUT_RECV
- , TB_AICO_TIMEOUT_SEND
- , TB_AICO_TIMEOUT_RECV
- , TB_AICO_TIMEOUT_SEND
- , TB_AICO_TIMEOUT_RECV
- , TB_AICO_TIMEOUT_SEND
- , TB_AICO_TIMEOUT_RECV
- , TB_AICO_TIMEOUT_SEND
- , TB_AICO_TIMEOUT_SEND
-
- , -1
- , -1
- , -1
- , -1
- , -1
-
- , -1
- };
- tb_assert_and_check_return_val(code < tb_arrayn(type), -1);
-
- // no timeout?
- tb_check_return_val(type[code] != -1, -1);
-
- // timeout
- return tb_aico_timeout((tb_aico_ref_t)aico, type[code]);
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-
-#endif
diff --git a/core/src/tbox/src/tbox/asio/deprecated/prefix.h b/core/src/tbox/src/tbox/asio/deprecated/prefix.h
deleted file mode 100644
index 7250b5905..000000000
--- a/core/src/tbox/src/tbox/asio/deprecated/prefix.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file prefix.h
- *
- */
-#ifndef TB_ASIO_DEPRECATED_PREFIX_H
-#define TB_ASIO_DEPRECATED_PREFIX_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "../prefix.h"
-#include "../../platform/prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the aioo ref type
-typedef __tb_typeref__(aioo);
-
-/// the aico ref type
-typedef __tb_typeref__(aico);
-
-/*! the aico pool ref type
- *
- * <pre>
- * |------------------------------------------------|
- * | astream |
- * |------------------------------------------------|
- * | addr | http | file | sock | .. |
- * '------------------------------------------------'
- * |
- * init: [aicp]
- * |
- * |------------------------------------------------|
- * addo: | aico0 aico1 aico2 aico3 ... | <= sock, file, and task aico
- * '------------------------------------------------'
- * |
- * [aicp]
- * |
- * post: |------------------------------------------------| <= only post one aice for the same aico util the aice is finished
- * aice: | aice0 aice1 aice2 aice3 ... | <---------------------------------------------------------------------------------
- * '------------------------------------------------' |
- * | |
- * [aicp] |
- * | <= input aices |
- * | |
- * '-------------------------------------------------------------- |
- * | | |
- * |--------------------------------------------------------------------------------------------------| |
- * | unix proactor | | windows proactor | |
- * |-----------------------------------------------------------------------|--------------------------| |
- * | | | | | |
- * | continue to spak aice | | |----- | |
- * | -------------------------------> | | | | | |
- * | | \/ [lock] | \/ | | |
- * aiop: |------|-------|-------|-------|---- ... --|-----| |-----| | done post | |
- * aico: | aico0 aico1 aico2 aico3 ... | | | | | | | | |
- * wait: |------|-------|-------|-------|---- ... --|-----| |aice4| | |----------------| | |
- * | | | | | | | | | | | |
- * | aice0 aice2 | |aice5| | | | | |
- * | | | | | | | | | | | |
- * | aice1 ... | |aice6| | | iocp | | |
- * | | | | | | | | | | |
- * | aice3 | |aice7| | | | | |
- * | | | | | | | | | | |
- * | ... | | ... | | | | | |
- * | | | | | | | | wait0 wait1 .. | | |
- * | | | | | ---------------- | |
- * | wait poll | |queue| | | | | |
- * '------------------------------------------------' '-----'-----------'--------------------------' |
- * /\ | [lock] | | |
- * | | | | |
- * | no data? wait aice --------------------------->----------------- |
- * |<-----------------------------| worker0 | worker1 | ... | <= done loop for workers |
- * -------------------<------------------------- |
- * | | | |
- * |---------------------------------------------| |
- * | aice0 | aice2 | ... | |
- * | aice1 | aice3 | ... | <= output aices |
- * | ... | aice4 | ... | |
- * | ... | ... | ... | |
- * '---------------------------------------------' |
- * | | | |
- * |---------------------------------------------| |
- * | caller0 | caller2 | ... | |
- * | caller1 | ... | ... | <= done callers |
- * | ... | caller3 | ... | |
- * | ... | ... | ... | |
- * '---------------------------------------------' |
- * | | |
- * ... ... |
- * post aice end ---- |
- * | | |
- * '---------------------|------------------------------------------------>'
- * |
- * kill: ... |
- * | |
- * exit: ... <---------'
- *
- * </pre>
- *
- */
-typedef __tb_typeref__(aicp);
-
-/*! the asio poll pool type
- *
- * @note only for sock and using level triggered mode
- *
- * <pre>
- * objs: |-----|------|------|--- ... ...---|-------|
- * wait: | |
- * evet: read writ ...
- * </pre>
- *
- */
-typedef __tb_typeref__(aiop);
-
-#endif
diff --git a/core/src/tbox/src/tbox/asio/deprecated/ssl.c b/core/src/tbox/src/tbox/asio/deprecated/ssl.c
deleted file mode 100644
index 3de448105..000000000
--- a/core/src/tbox/src/tbox/asio/deprecated/ssl.c
+++ /dev/null
@@ -1,1366 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file ssl.c
- * @ingroup asio
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "aicp_ssl"
-#define TB_TRACE_MODULE_DEBUG (1)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "ssl.h"
-#include "aico.h"
-#include "aicp.h"
-#include "../../network/network.h"
-#include "../../platform/platform.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the aicp impl open type
-typedef struct __tb_aicp_ssl_open_t
-{
- // the func
- tb_aicp_ssl_open_func_t func;
-
- // the priv
- tb_cpointer_t priv;
-
-}tb_aicp_ssl_open_t;
-
-// the aicp impl clos type
-typedef struct __tb_aicp_ssl_clos_t
-{
- // the func
- tb_aicp_ssl_clos_func_t func;
-
- // the priv
- tb_cpointer_t priv;
-
-}tb_aicp_ssl_clos_t;
-
-// the aicp impl read type
-typedef struct __tb_aicp_ssl_read_t
-{
- // the func
- tb_aicp_ssl_read_func_t func;
-
- // the data
- tb_byte_t* data;
-
- // the size
- tb_size_t size;
-
- // the priv
- tb_cpointer_t priv;
-
- // the delay
- tb_size_t delay;
-
-}tb_aicp_ssl_read_t;
-
-// the aicp impl writ type
-typedef struct __tb_aicp_ssl_writ_t
-{
- // the func
- tb_aicp_ssl_writ_func_t func;
-
- // the data
- tb_byte_t const* data;
-
- // the size
- tb_size_t size;
-
- // the priv
- tb_cpointer_t priv;
-
-}tb_aicp_ssl_writ_t;
-
-// the aicp impl task type
-typedef struct __tb_aicp_ssl_task_t
-{
- // the func
- tb_aicp_ssl_task_func_t func;
-
- // the priv
- tb_cpointer_t priv;
-
-}tb_aicp_ssl_task_t;
-
-/// the aicp impl close opening type
-typedef struct __tb_aicp_ssl_clos_opening_t
-{
- /// the func
- tb_aicp_ssl_open_func_t func;
-
- /// the priv
- tb_cpointer_t priv;
-
- /// the open state
- tb_size_t state;
-
-}tb_aicp_ssl_clos_opening_t;
-
-// the aicp impl type
-typedef struct __tb_aicp_ssl_impl_t
-{
- // the ssl
- tb_ssl_ref_t ssl;
-
- // the aicp
- tb_aicp_ref_t aicp;
-
- // the aico
- tb_aico_ref_t aico;
-
- // the func
- union
- {
- tb_aicp_ssl_open_t open;
- tb_aicp_ssl_read_t read;
- tb_aicp_ssl_writ_t writ;
- tb_aicp_ssl_task_t task;
- tb_aicp_ssl_clos_t clos;
-
- } func;
-
- // the open and func
- union
- {
- tb_aicp_ssl_read_t read;
- tb_aicp_ssl_writ_t writ;
-
- } open_and;
-
- // the clos opening
- tb_aicp_ssl_clos_opening_t clos_opening;
-
- // the post
- struct
- {
- // the post func
- tb_bool_t (*func)(tb_aice_ref_t aice);
-
- // the post delay
- tb_size_t delay;
-
- // the real size
- tb_long_t real;
-
- // the read or writ data
- tb_byte_t* data;
-
- // the read or writ size
- tb_size_t size;
-
- // post read?
- tb_bool_t read;
-
- // have post?
- tb_bool_t post;
-
- } post;
-
- // the timeout
- tb_long_t timeout;
-
- /* the state
- *
- * TB_STATE_CLOSED
- * TB_STATE_OPENED
- * TB_STATE_OPENING
- * TB_STATE_KILLING
- */
- tb_atomic_t state;
-
- // the read data
- tb_buffer_t read_data;
-
- // the writ data
- tb_buffer_t writ_data;
-
-}tb_aicp_ssl_impl_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static tb_long_t tb_aicp_ssl_fill_read(tb_aicp_ssl_impl_t* impl, tb_byte_t* data, tb_size_t size)
-{
- // check
- tb_assert_and_check_return_val(impl, -1);
-
- // done
- tb_long_t real = -1;
- do
- {
- // check
- tb_assert_and_check_break(impl->aico);
- tb_assert_and_check_break(data && size && impl->post.real >= 0);
-
- // save real
- tb_size_t read_real = impl->post.real;
-
- // clear real
- impl->post.real = -1;
-
- // check
- tb_assert_and_check_break(read_real <= size);
-
- // the data and size
- tb_byte_t* read_data = tb_buffer_data(&impl->read_data);
- tb_size_t read_size = tb_buffer_size(&impl->read_data);
- tb_assert_and_check_break(read_data && read_size && size <= read_size);
-
- // copy data
- tb_memcpy(data, read_data, read_real);
-
- // trace
- tb_trace_d("[aico:%p]: read: fill: %lu: ok", impl->aico, read_real);
-
- // read ok
- real = read_real;
-
- } while (0);
-
- // ok?
- return real;
-}
-static tb_long_t tb_aicp_ssl_fill_writ(tb_aicp_ssl_impl_t* impl, tb_byte_t const* data, tb_size_t size)
-{
- // check
- tb_assert_and_check_return_val(impl, -1);
-
- // done
- tb_long_t real = -1;
- do
- {
- // check
- tb_assert_and_check_break(impl->aico);
- tb_assert_and_check_break(size && impl->post.real >= 0);
-
- // save real
- tb_size_t writ_real = impl->post.real;
-
- // clear real
- impl->post.real = -1;
-
- // check
- tb_assert_and_check_break(writ_real <= size);
-
- // trace
- tb_trace_d("[aico:%p]: writ: try: %lu: ok", impl->aico, writ_real);
-
- // writ ok
- real = writ_real;
-
- } while (0);
-
- // ok?
- return real;
-}
-static tb_bool_t tb_aicp_ssl_done_post(tb_aicp_ssl_impl_t* impl)
-{
- // check
- tb_assert_and_check_return_val(impl, tb_false);
-
- // done
- tb_bool_t ok = tb_false;
- do
- {
- // check
- tb_assert_and_check_break(impl->post.post && impl->post.data && impl->post.size && impl->post.func);
-
- // check
- tb_assert_and_check_break(impl->aico);
-
- // post read?
- if (impl->post.read)
- {
- // trace
- tb_trace_d("[aico:%p]: post: read: %lu: ..", impl->aico, impl->post.size);
-
- // post read
- if (!tb_aico_recv_after(impl->aico, impl->post.delay, impl->post.data, impl->post.size, impl->post.func, impl)) break;
- }
- // post writ?
- else
- {
- // trace
- tb_trace_d("[aico:%p]: post: writ: %lu: ..", impl->aico, impl->post.size);
-
- // post writ
- if (!tb_aico_send_after(impl->aico, impl->post.delay, impl->post.data, impl->post.size, impl->post.func, impl)) break;
- }
-
- // delay only for first
- impl->post.delay = 0;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // ok?
- return ok;
-}
-static tb_void_t tb_aicp_ssl_clos_clear(tb_aicp_ssl_impl_t* impl)
-{
- // check
- tb_assert_and_check_return(impl);
-
- // close impl
- if (impl->ssl && impl->aico)
- {
- // init bio sock, need some blocking time for closing
- tb_ssl_set_bio_sock(impl->ssl, tb_aico_sock(impl->aico));
-
- // close it
- tb_ssl_clos(impl->ssl);
- }
-
- // clear data
- tb_buffer_clear(&impl->read_data);
- tb_buffer_clear(&impl->writ_data);
-
- // clear real
- impl->post.real = 0;
- impl->post.real = 0;
-
- // closed
- tb_atomic_set(&impl->state, TB_STATE_CLOSED);
-}
-static tb_void_t tb_aicp_ssl_clos_opening(tb_aicp_ssl_ref_t ssl, tb_size_t state, tb_cpointer_t priv)
-{
- // check
- tb_aicp_ssl_impl_t* impl = (tb_aicp_ssl_impl_t*)ssl;
- tb_assert_and_check_return(impl);
-
- // trace
- tb_trace_d("[aico:%p]: clos: opening: state: %s", impl->aico, tb_state_cstr(impl->clos_opening.state));
-
- // done func
- if (impl->clos_opening.func) impl->clos_opening.func(ssl, impl->clos_opening.state, impl->clos_opening.priv);
-}
-static tb_bool_t tb_aicp_ssl_open_func(tb_aicp_ssl_impl_t* impl, tb_size_t state, tb_aicp_ssl_open_func_t func, tb_cpointer_t priv)
-{
- // check
- tb_assert_and_check_return_val(impl, tb_false);
-
- // ok?
- tb_bool_t ok = tb_true;
- if (state == TB_STATE_OK || !impl->aico)
- {
- // opened
- tb_atomic_set(&impl->state, TB_STATE_OPENED);
-
- // done func
- if (func) ok = func((tb_aicp_ssl_ref_t)impl, state, priv);
- }
- // failed?
- else
- {
- // init func and state
- impl->clos_opening.func = func;
- impl->clos_opening.priv = priv;
- impl->clos_opening.state = state;
-
- // close it
- tb_aicp_ssl_clos((tb_aicp_ssl_ref_t)impl, tb_aicp_ssl_clos_opening, tb_null);
- }
-
- // ok?
- return ok;
-}
-static tb_bool_t tb_aicp_ssl_open_done(tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(aice && (aice->code == TB_AICE_CODE_RECV || aice->code == TB_AICE_CODE_SEND), tb_false);
-
- // the impl
- tb_aicp_ssl_impl_t* impl = (tb_aicp_ssl_impl_t*)aice->priv;
- tb_assert_and_check_return_val(impl && impl->func.open.func, tb_false);
-
- // the real
- tb_size_t real = aice->code == TB_AICE_CODE_RECV? aice->u.recv.real : aice->u.send.real;
-
- // trace
- tb_trace_d("[aico:%p]: open: done: real: %lu, state: %s", impl->aico, real, tb_state_cstr(aice->state));
-
- // done
- tb_size_t state = TB_STATE_SOCK_SSL_UNKNOWN_ERROR;
- do
- {
- // clear post
- impl->post.post = tb_false;
- impl->post.data = tb_null;
- impl->post.size = 0;
-
- // failed or closed?
- if (aice->state != TB_STATE_OK)
- {
- state = aice->state;
- break;
- }
-
- // save the real size
- impl->post.real = real;
-
- // trace
- tb_trace_d("[aico:%p]: open: done: try: ..", impl->aico);
-
- // try opening it
- tb_long_t ok = tb_ssl_open_try(impl->ssl);
-
- // trace
- tb_trace_d("[aico:%p]: open: done: try: %ld", impl->aico, ok);
-
- // ok?
- if (ok > 0)
- {
- // done func
- tb_aicp_ssl_open_func(impl, TB_STATE_OK, impl->func.open.func, impl->func.open.priv);
- }
- // failed?
- else if (ok < 0)
- {
- // save state
- state = tb_ssl_state(impl->ssl);
- break;
- }
- // have post? continue it
- else if (impl->post.post)
- {
- // post it
- if (!tb_aicp_ssl_done_post(impl))
- {
- // trace
- tb_trace_e("[aico:%p]: open: done: post failed!", impl->aico);
- break;
- }
- }
- else
- {
- // trace
- tb_trace_d("[aico:%p]: open: done: no post!", impl->aico);
- }
-
- // ok
- state = TB_STATE_OK;
-
- } while (0);
-
- // failed?
- if (state != TB_STATE_OK)
- {
- // done func
- tb_aicp_ssl_open_func(impl, state, impl->func.open.func, impl->func.open.priv);
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_aicp_ssl_read_done(tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(aice && (aice->code == TB_AICE_CODE_RECV || aice->code == TB_AICE_CODE_SEND), tb_false);
-
- // the impl
- tb_aicp_ssl_impl_t* impl = (tb_aicp_ssl_impl_t*)aice->priv;
- tb_assert_and_check_return_val(impl && impl->func.read.func, tb_false);
-
- // the real
- tb_size_t real = aice->code == TB_AICE_CODE_RECV? aice->u.recv.real : aice->u.send.real;
-
- // trace
- tb_trace_d("[aico:%p]: read: done: real: %lu, state: %s", impl->aico, real, tb_state_cstr(aice->state));
-
- // done
- tb_size_t state = TB_STATE_SOCK_SSL_UNKNOWN_ERROR;
- do
- {
- // clear post
- impl->post.post = tb_false;
- impl->post.data = tb_null;
- impl->post.size = 0;
-
- // failed or closed?
- if (aice->state != TB_STATE_OK)
- {
- state = aice->state;
- break;
- }
-
- // save the real size
- impl->post.real = real;
-
- // trace
- tb_trace_d("[aico:%p]: read: done: try: %lu: ..", impl->aico, impl->func.read.size);
-
- // try reading it
- tb_long_t real = tb_ssl_read(impl->ssl, impl->func.read.data, impl->func.read.size);
-
- // trace
- tb_trace_d("[aico:%p]: read: done: try: %lu: %ld", impl->aico, impl->func.read.size, real);
-
- // ok?
- if (real > 0)
- {
- // done func
- impl->func.read.func((tb_aicp_ssl_ref_t)impl, TB_STATE_OK, impl->func.read.data, real, impl->func.read.size, impl->func.read.priv);
- }
- // failed?
- else if (real < 0)
- {
- // save state
- state = tb_ssl_state(impl->ssl);
- break;
- }
- // have post? continue it
- else if (impl->post.post)
- {
- // post it
- if (!tb_aicp_ssl_done_post(impl))
- {
- // trace
- tb_trace_e("[aico:%p]: read: done: post failed!", impl->aico);
- break;
- }
- }
- else
- {
- // trace
- tb_trace_d("[aico:%p]: read: done: no post!", impl->aico);
-
- // done func
- impl->func.read.func((tb_aicp_ssl_ref_t)impl, TB_STATE_OK, impl->func.read.data, 0, impl->func.read.size, impl->func.read.priv);
- }
-
- // ok
- state = TB_STATE_OK;
-
- } while (0);
-
- // failed?
- if (state != TB_STATE_OK)
- {
- // done func
- impl->func.read.func((tb_aicp_ssl_ref_t)impl, state, impl->func.read.data, 0, impl->func.read.size, impl->func.read.priv);
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_aicp_ssl_writ_done(tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(aice && (aice->code == TB_AICE_CODE_RECV || aice->code == TB_AICE_CODE_SEND), tb_false);
-
- // the impl
- tb_aicp_ssl_impl_t* impl = (tb_aicp_ssl_impl_t*)aice->priv;
- tb_assert_and_check_return_val(impl && impl->func.writ.func, tb_false);
-
- // the real
- tb_size_t real = aice->code == TB_AICE_CODE_RECV? aice->u.recv.real : aice->u.send.real;
-
- // trace
- tb_trace_d("[aico:%p]: writ: done: real: %lu, state: %s", impl->aico, real, tb_state_cstr(aice->state));
-
- // done
- tb_size_t state = TB_STATE_SOCK_SSL_UNKNOWN_ERROR;
- do
- {
- // clear post
- impl->post.post = tb_false;
- impl->post.data = tb_null;
- impl->post.size = 0;
-
- // failed or closed?
- if (aice->state != TB_STATE_OK)
- {
- state = aice->state;
- break;
- }
-
- // save the real size
- impl->post.real = real;
-
- // trace
- tb_trace_d("[aico:%p]: writ: done: try: %lu: ..", impl->aico, impl->func.writ.size);
-
- // try writing it
- tb_long_t real = tb_ssl_writ(impl->ssl, impl->func.writ.data, impl->func.writ.size);
-
- // trace
- tb_trace_d("[aico:%p]: writ: done: try: %lu: %ld", impl->aico, impl->func.writ.size, real);
-
- // ok?
- if (real > 0)
- {
- // done func
- impl->func.writ.func((tb_aicp_ssl_ref_t)impl, TB_STATE_OK, impl->func.writ.data, real, impl->func.writ.size, impl->func.writ.priv);
- }
- // failed?
- else if (real < 0)
- {
- // save state
- state = tb_ssl_state(impl->ssl);
- break;
- }
- // have post? continue it
- else if (impl->post.post)
- {
- // post it
- if (!tb_aicp_ssl_done_post(impl))
- {
- // trace
- tb_trace_e("[aico:%p]: writ: done: post failed!", impl->aico);
- break;
- }
- }
- else
- {
- // trace
- tb_trace_d("[aico:%p]: writ: done: no post!", impl->aico);
-
- // done func
- impl->func.writ.func((tb_aicp_ssl_ref_t)impl, TB_STATE_OK, impl->func.writ.data, 0, impl->func.writ.size, impl->func.writ.priv);
- }
-
- // ok
- state = TB_STATE_OK;
-
- } while (0);
-
- // failed?
- if (state != TB_STATE_OK)
- {
- // done func
- impl->func.writ.func((tb_aicp_ssl_ref_t)impl, state, impl->func.writ.data, 0, impl->func.writ.size, impl->func.writ.priv);
- }
-
- // ok
- return tb_true;
-}
-static tb_long_t tb_aicp_ssl_read_func(tb_cpointer_t priv, tb_byte_t* data, tb_size_t size)
-{
- // check
- tb_aicp_ssl_impl_t* impl = (tb_aicp_ssl_impl_t*)priv;
- tb_assert_and_check_return_val(impl && impl->post.func && !impl->post.post, -1);
-
- // done
- tb_size_t state = TB_STATE_SOCK_SSL_UNKNOWN_ERROR;
- do
- {
- // fill to read it?
- if (impl->post.real >= 0) return tb_aicp_ssl_fill_read(impl, data, size);
-
- // resize data
- if (tb_buffer_size(&impl->read_data) < size)
- tb_buffer_resize(&impl->read_data, size);
-
- // the data and size
- tb_byte_t* read_data = tb_buffer_data(&impl->read_data);
- tb_size_t read_size = tb_buffer_size(&impl->read_data);
- tb_assert_and_check_break(read_data && read_size && size <= read_size);
-
- // post read
- impl->post.post = tb_true;
- impl->post.read = tb_true;
- impl->post.data = read_data;
- impl->post.size = size;
-
- // ok
- state = TB_STATE_OK;
-
- } while (0);
-
- // read failed or continue?
- return state != TB_STATE_OK? -1 : 0;
-}
-static tb_long_t tb_aicp_ssl_writ_func(tb_cpointer_t priv, tb_byte_t const* data, tb_size_t size)
-{
- // check
- tb_aicp_ssl_impl_t* impl = (tb_aicp_ssl_impl_t*)priv;
- tb_assert_and_check_return_val(impl && impl->post.func && !impl->post.post, -1);
-
- // done
- tb_size_t state = TB_STATE_SOCK_SSL_UNKNOWN_ERROR;
- do
- {
- // fill to writ it?
- if (impl->post.real >= 0) return tb_aicp_ssl_fill_writ(impl, data, size);
-
- // save data
- tb_buffer_memncpy(&impl->writ_data, data, size);
-
- // the data and size
- tb_byte_t* writ_data = tb_buffer_data(&impl->writ_data);
- tb_size_t writ_size = tb_buffer_size(&impl->writ_data);
- tb_assert_and_check_break(writ_data && writ_size && size == writ_size);
-
- // post writ
- impl->post.post = tb_true;
- impl->post.read = tb_false;
- impl->post.data = writ_data;
- impl->post.size = writ_size;
-
- // ok
- state = TB_STATE_OK;
-
- } while (0);
-
- // ok?
- return state != TB_STATE_OK? -1 : 0;
-}
-static tb_bool_t tb_aicp_ssl_open_and_read(tb_aicp_ssl_ref_t ssl, tb_size_t state, tb_cpointer_t priv)
-{
- // check
- tb_aicp_ssl_read_t* read = (tb_aicp_ssl_read_t*)priv;
- tb_assert_and_check_return_val(ssl && read && read->func, tb_false);
-
- // done
- tb_bool_t ok = tb_true;
- do
- {
- // check
- tb_check_break(state == TB_STATE_OK);
-
- // clear state
- state = TB_STATE_SOCK_SSL_UNKNOWN_ERROR;
-
- // post read
- if (!tb_aicp_ssl_read(ssl, read->data, read->size, read->func, read->priv)) break;
-
- // ok
- state = TB_STATE_OK;
-
- } while (0);
-
- // failed?
- if (state != TB_STATE_OK)
- {
- // done func
- ok = read->func(ssl, state, read->data, 0, read->size, read->priv);
- }
-
- // ok?
- return ok;
-}
-static tb_bool_t tb_aicp_ssl_open_and_writ(tb_aicp_ssl_ref_t ssl, tb_size_t state, tb_cpointer_t priv)
-{
- // check
- tb_aicp_ssl_writ_t* writ = (tb_aicp_ssl_writ_t*)priv;
- tb_assert_and_check_return_val(ssl && writ && writ->func, tb_false);
-
- // done
- tb_bool_t ok = tb_true;
- do
- {
- // check
- tb_check_break(state == TB_STATE_OK);
-
- // clear state
- state = TB_STATE_SOCK_SSL_UNKNOWN_ERROR;
-
- // post writ
- if (!tb_aicp_ssl_writ(ssl, writ->data, writ->size, writ->func, writ->priv)) break;
-
- // ok
- state = TB_STATE_OK;
-
- } while (0);
-
- // failed?
- if (state != TB_STATE_OK)
- {
- // done func
- ok = writ->func(ssl, state, writ->data, 0, writ->size, writ->priv);
- }
-
- // ok?
- return ok;
-}
-static tb_bool_t tb_aicp_ssl_done_task(tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(aice && aice->code == TB_AICE_CODE_RUNTASK, tb_false);
-
- // the impl
- tb_aicp_ssl_impl_t* impl = (tb_aicp_ssl_impl_t*)aice->priv;
- tb_assert_and_check_return_val(impl && impl->func.task.func, tb_false);
-
- // trace
- tb_trace_d("[aico:%p]: task: done: state: %s", impl->aico, tb_state_cstr(aice->state));
-
- // done func
- impl->func.task.func((tb_aicp_ssl_ref_t)impl, aice->state, impl->post.delay, impl->func.task.priv);
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_aicp_ssl_done_clos(tb_aice_ref_t aice)
-{
- // check
- tb_assert_and_check_return_val(aice && aice->aico && aice->code == TB_AICE_CODE_RUNTASK, tb_false);
-
- // the impl
- tb_aicp_ssl_impl_t* impl = (tb_aicp_ssl_impl_t*)aice->priv;
- tb_assert_and_check_return_val(impl && impl->func.clos.func, tb_false);
-
- // trace
- tb_trace_d("[aico:%p]: clos: notify: ..", impl->aico);
-
- // clear impl
- tb_aicp_ssl_clos_clear(impl);
-
- // done func
- impl->func.clos.func((tb_aicp_ssl_ref_t)impl, TB_STATE_OK, impl->func.clos.priv);
-
- // trace
- tb_trace_d("[aico:%p]: clos: notify: ok", impl->aico);
-
- // ok
- return tb_true;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-tb_aicp_ssl_ref_t tb_aicp_ssl_init(tb_aicp_ref_t aicp, tb_bool_t bserver)
-{
- // check
- tb_assert_and_check_return_val(aicp, tb_null);
-
- // done
- tb_bool_t ok = tb_false;
- tb_aicp_ssl_impl_t* impl = tb_null;
- do
- {
- // make impl
- impl = tb_malloc0_type(tb_aicp_ssl_impl_t);
- tb_assert_and_check_break(impl);
-
- // init state
- impl->state = TB_STATE_CLOSED;
-
- // init aicp
- impl->aicp = aicp;
-
- // init impl
- impl->ssl = tb_ssl_init(bserver);
- tb_assert_and_check_break(impl->ssl);
-
- // init read data
- if (!tb_buffer_init(&impl->read_data)) break;
-
- // init writ data
- if (!tb_buffer_init(&impl->writ_data)) break;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (impl) tb_aicp_ssl_exit((tb_aicp_ssl_ref_t)impl);
- impl = tb_null;
- }
-
- // ok?
- return (tb_aicp_ssl_ref_t)impl;
-}
-tb_void_t tb_aicp_ssl_kill(tb_aicp_ssl_ref_t ssl)
-{
- // check
- tb_aicp_ssl_impl_t* impl = (tb_aicp_ssl_impl_t*)ssl;
- tb_assert_and_check_return(impl);
-
- // kill it
- tb_size_t state = tb_atomic_fetch_and_set(&impl->state, TB_STATE_KILLING);
- tb_check_return(state != TB_STATE_KILLING);
-
- // trace
- tb_trace_d("[aico:%p]: kill: ..", impl->aico);
-
- // kill aico
- if (impl->aico) tb_aico_kill(impl->aico);
-}
-tb_bool_t tb_aicp_ssl_exit(tb_aicp_ssl_ref_t ssl)
-{
- // check
- tb_aicp_ssl_impl_t* impl = (tb_aicp_ssl_impl_t*)ssl;
- tb_assert_and_check_return_val(impl, tb_false);
-
- // trace
- tb_trace_d("[aico:%p]: exit: ..", impl->aico);
-
- // try closing it
- tb_size_t tryn = 30;
- tb_bool_t ok = tb_false;
- while (!(ok = tb_aicp_ssl_clos_try(ssl)) && tryn--)
- {
- // wait some time
- tb_msleep(200);
- }
-
- // close failed?
- if (!ok)
- {
- // trace
- tb_trace_e("[aico:%p]: exit: failed!", impl->aico);
- return tb_false;
- }
-
- // exit impl
- if (impl->ssl) tb_ssl_exit(impl->ssl);
- impl->ssl = tb_null;
-
- // exit data
- tb_buffer_exit(&impl->read_data);
- tb_buffer_exit(&impl->writ_data);
-
- // trace
- tb_trace_d("[aico:%p]: exit: ok", impl->aico);
-
- // exit it
- tb_free(impl);
-
- // ok
- return tb_true;
-}
-tb_void_t tb_aicp_ssl_set_aico(tb_aicp_ssl_ref_t ssl, tb_aico_ref_t aico)
-{
- // check
- tb_aicp_ssl_impl_t* impl = (tb_aicp_ssl_impl_t*)ssl;
- tb_assert_and_check_return(impl);
-
- // save aico
- impl->aico = aico;
-}
-tb_void_t tb_aicp_ssl_set_timeout(tb_aicp_ssl_ref_t ssl, tb_long_t timeout)
-{
- // check
- tb_aicp_ssl_impl_t* impl = (tb_aicp_ssl_impl_t*)ssl;
- tb_assert_and_check_return(impl);
-
- // save timeout
- impl->timeout = timeout;
-}
-tb_bool_t tb_aicp_ssl_open(tb_aicp_ssl_ref_t ssl, tb_aicp_ssl_open_func_t func, tb_cpointer_t priv)
-{
- // check
- tb_aicp_ssl_impl_t* impl = (tb_aicp_ssl_impl_t*)ssl;
- tb_assert_and_check_return_val(impl && func, tb_false);
-
- // done
- do
- {
- // set opening
- tb_size_t state = tb_atomic_fetch_and_pset(&impl->state, TB_STATE_CLOSED, TB_STATE_OPENING);
-
- // opened? done func directly
- if (state == TB_STATE_OPENED)
- {
- func(ssl, TB_STATE_OK, priv);
- break;
- }
-
- // must be closed
- tb_assert_and_check_return_val(state == TB_STATE_CLOSED, tb_false);
-
- // check
- tb_assert_and_check_return_val(impl->aicp && impl->ssl && impl->aico, tb_false);
-
- // killed?
- if (TB_STATE_KILLING == tb_atomic_get(&impl->state))
- {
- // done func
- tb_aicp_ssl_open_func(impl, TB_STATE_KILLED, func, priv);
- break;
- }
-
- // init timeout
- if (impl->timeout)
- {
- tb_aico_timeout_set(impl->aico, TB_AICO_TIMEOUT_RECV, impl->timeout);
- tb_aico_timeout_set(impl->aico, TB_AICO_TIMEOUT_SEND, impl->timeout);
- }
-
- // save func
- impl->func.open.func = func;
- impl->func.open.priv = priv;
-
- // init post
- impl->post.func = tb_aicp_ssl_open_done;
- impl->post.delay = 0;
- impl->post.post = tb_false;
- impl->post.data = tb_null;
- impl->post.size = 0;
- impl->post.real = -1;
-
- // init post func
- tb_ssl_set_bio_func(impl->ssl, tb_aicp_ssl_read_func, tb_aicp_ssl_writ_func, tb_null, impl);
-
- // try opening it
- tb_long_t r = tb_ssl_open_try(impl->ssl);
-
- // ok
- if (r > 0)
- {
- // done func
- tb_aicp_ssl_open_func(impl, TB_STATE_OK, func, priv);
- }
- // failed?
- else if (r < 0)
- {
- // done func
- tb_aicp_ssl_open_func(impl, tb_ssl_state(impl->ssl), func, priv);
- }
- // have post? continue it
- else if (impl->post.post)
- {
- // post it
- if (!tb_aicp_ssl_done_post(impl))
- {
- // trace
- tb_trace_e("[aico:%p]: open: post failed!", impl->aico);
-
- // done func
- tb_aicp_ssl_open_func(impl, TB_STATE_SOCK_SSL_UNKNOWN_ERROR, func, priv);
- }
- }
- else
- {
- // trace
- tb_trace_e("[aico:%p]: open: no post!", impl->aico);
-
- // done func
- tb_aicp_ssl_open_func(impl, TB_STATE_SOCK_SSL_UNKNOWN_ERROR, func, priv);
- }
-
- } while (0);
-
- // post or done func ok
- return tb_true;
-}
-tb_bool_t tb_aicp_ssl_clos(tb_aicp_ssl_ref_t ssl, tb_aicp_ssl_clos_func_t func, tb_cpointer_t priv)
-{
- // check
- tb_aicp_ssl_impl_t* impl = (tb_aicp_ssl_impl_t*)ssl;
- tb_assert_and_check_return_val(impl && func, tb_false);
-
- // trace
- tb_trace_d("[aico:%p]: clos: ..", impl->aico);
-
- // try closing ok?
- if (tb_aicp_ssl_clos_try(ssl))
- {
- // done func
- func(ssl, TB_STATE_OK, priv);
- return tb_true;
- }
-
- // init func
- impl->func.clos.func = func;
- impl->func.clos.priv = priv;
-
- // clos aico
- if (impl->aico && tb_aico_task_run(impl->aico, 0, tb_aicp_ssl_done_clos, impl));
- else
- {
- // clear impl
- tb_aicp_ssl_clos_clear(impl);
-
- // done func
- impl->func.clos.func(ssl, TB_STATE_OK, impl->func.clos.priv);
- }
-
- // ok
- return tb_true;
-}
-tb_bool_t tb_aicp_ssl_clos_try(tb_aicp_ssl_ref_t ssl)
-{
- // check
- tb_aicp_ssl_impl_t* impl = (tb_aicp_ssl_impl_t*)ssl;
- tb_assert_and_check_return_val(impl, tb_false);
-
- // trace
- tb_trace_d("[aico:%p]: clos: try: ..", impl->aico);
-
- // done
- tb_bool_t ok = tb_true;
- do
- {
- // closed? ok
- if (TB_STATE_CLOSED == tb_atomic_get(&impl->state)) break;
-
- // no aico? ok
- if (!impl->aico) break;
-
- // failed
- ok = tb_false;
-
- } while (0);
-
- // ok? closed
- if (ok) tb_atomic_set(&impl->state, TB_STATE_CLOSED);
-
- // trace
- tb_trace_d("[aico:%p]: clos: try: %s", impl->aico, ok? "ok" : "no");
-
- // ok?
- return ok;
-}
-tb_bool_t tb_aicp_ssl_read(tb_aicp_ssl_ref_t ssl, tb_byte_t* data, tb_size_t size, tb_aicp_ssl_read_func_t func, tb_cpointer_t priv)
-{
- return tb_aicp_ssl_read_after(ssl, 0, data, size, func, priv);
-}
-tb_bool_t tb_aicp_ssl_writ(tb_aicp_ssl_ref_t ssl, tb_byte_t const* data, tb_size_t size, tb_aicp_ssl_writ_func_t func, tb_cpointer_t priv)
-{
- return tb_aicp_ssl_writ_after(ssl, 0, data, size, func, priv);
-}
-tb_bool_t tb_aicp_ssl_read_after(tb_aicp_ssl_ref_t ssl, tb_size_t delay, tb_byte_t* data, tb_size_t size, tb_aicp_ssl_read_func_t func, tb_cpointer_t priv)
-{
- // check
- tb_aicp_ssl_impl_t* impl = (tb_aicp_ssl_impl_t*)ssl;
- tb_assert_and_check_return_val(impl && data && size && func, tb_false);
-
- // trace
- tb_trace_d("[aico:%p]: read: %lu, after: %lu", impl->aico, size, delay);
-
- // opened?
- tb_assert_and_check_return_val(TB_STATE_OPENED == tb_atomic_get(&impl->state), tb_false);
-
- // check
- tb_assert_and_check_return_val(impl->aicp && impl->ssl && impl->aico, tb_false);
-
- // done
- do
- {
- // save func
- impl->func.read.func = func;
- impl->func.read.priv = priv;
- impl->func.read.data = data;
- impl->func.read.size = size;
-
- // init post
- impl->post.func = tb_aicp_ssl_read_done;
- impl->post.delay = delay;
- impl->post.post = tb_false;
- impl->post.data = tb_null;
- impl->post.size = 0;
- impl->post.real = -1;
-
- // init post func
- tb_ssl_set_bio_func(impl->ssl, tb_aicp_ssl_read_func, tb_aicp_ssl_writ_func, tb_null, impl);
-
- // try reading it
- tb_long_t real = tb_ssl_read(impl->ssl, data, size);
-
- // ok
- if (real > 0)
- {
- // done func
- func(ssl, TB_STATE_OK, data, real, size, priv);
- }
- // failed?
- else if (real < 0)
- {
- // done func
- func(ssl, tb_ssl_state(impl->ssl), data, 0, size, priv);
- }
- // have post? continue it
- else if (impl->post.post)
- {
- // post it
- if (!tb_aicp_ssl_done_post(impl))
- {
- // trace
- tb_trace_e("[aico:%p]: read: post failed!", impl->aico);
-
- // done func
- func(ssl, TB_STATE_SOCK_SSL_UNKNOWN_ERROR, data, 0, size, priv);
- }
- }
- else
- {
- // trace
- tb_trace_e("[aico:%p]: read: no post!", impl->aico);
-
- // done func
- func(ssl, TB_STATE_SOCK_SSL_UNKNOWN_ERROR, data, 0, size, priv);
- }
-
- } while (0);
-
- // post or done func ok
- return tb_true;
-}
-tb_bool_t tb_aicp_ssl_writ_after(tb_aicp_ssl_ref_t ssl, tb_size_t delay, tb_byte_t const* data, tb_size_t size, tb_aicp_ssl_writ_func_t func, tb_cpointer_t priv)
-{
- // check
- tb_aicp_ssl_impl_t* impl = (tb_aicp_ssl_impl_t*)ssl;
- tb_assert_and_check_return_val(impl && data && size && func, tb_false);
-
- // trace
- tb_trace_d("[aico:%p]: writ: %lu, after: %lu", impl->aico, size, delay);
-
- // opened?
- tb_assert_and_check_return_val(TB_STATE_OPENED == tb_atomic_get(&impl->state), tb_false);
-
- // check
- tb_assert_and_check_return_val(impl->aicp && impl->ssl && impl->aico, tb_false);
-
- // done
- do
- {
- // save func
- impl->func.writ.func = func;
- impl->func.writ.priv = priv;
- impl->func.writ.data = data;
- impl->func.writ.size = size;
-
- // init post
- impl->post.func = tb_aicp_ssl_writ_done;
- impl->post.delay = delay;
- impl->post.post = tb_false;
- impl->post.data = tb_null;
- impl->post.size = 0;
- impl->post.real = -1;
-
- // init post func
- tb_ssl_set_bio_func(impl->ssl, tb_aicp_ssl_read_func, tb_aicp_ssl_writ_func, tb_null, impl);
-
- // try writing it
- tb_long_t real = tb_ssl_writ(impl->ssl, data, size);
-
- // ok
- if (real > 0)
- {
- // done func
- func(ssl, TB_STATE_OK, data, real, size, priv);
- }
- // failed?
- else if (real < 0)
- {
- // done func
- func(ssl, tb_ssl_state(impl->ssl), data, 0, size, priv);
- }
- // have post? continue it
- else if (impl->post.post)
- {
- // post it
- if (!tb_aicp_ssl_done_post(impl))
- {
- // trace
- tb_trace_e("[aico:%p]: writ: post failed!", impl->aico);
-
- // done func
- func(ssl, TB_STATE_SOCK_SSL_UNKNOWN_ERROR, data, 0, size, priv);
- }
- }
- else
- {
- // trace
- tb_trace_e("[aico:%p]: writ: no post!", impl->aico);
-
- // done func
- func(ssl, TB_STATE_SOCK_SSL_UNKNOWN_ERROR, data, 0, size, priv);
- }
-
- } while (0);
-
- // post or done func ok
- return tb_true;
-}
-tb_bool_t tb_aicp_ssl_task(tb_aicp_ssl_ref_t ssl, tb_size_t delay, tb_aicp_ssl_task_func_t func, tb_cpointer_t priv)
-{
- // check
- tb_aicp_ssl_impl_t* impl = (tb_aicp_ssl_impl_t*)ssl;
- tb_assert_and_check_return_val(impl && impl->aico && func, tb_false);
-
- // save func
- impl->func.task.func = func;
- impl->func.task.priv = priv;
- impl->post.delay = delay;
-
- // run task
- return tb_aico_task_run(impl->aico, delay, tb_aicp_ssl_done_task, impl);
-}
-tb_bool_t tb_aicp_ssl_open_read(tb_aicp_ssl_ref_t ssl, tb_byte_t* data, tb_size_t size, tb_aicp_ssl_read_func_t func, tb_cpointer_t priv)
-{
- // check
- tb_aicp_ssl_impl_t* impl = (tb_aicp_ssl_impl_t*)ssl;
- tb_assert_and_check_return_val(impl && data && size && func, tb_false);
-
- // not opened? open it first
- if (TB_STATE_CLOSED == tb_atomic_get(&impl->state))
- {
- impl->open_and.read.func = func;
- impl->open_and.read.data = data;
- impl->open_and.read.size = size;
- impl->open_and.read.priv = priv;
- return tb_aicp_ssl_open(ssl, tb_aicp_ssl_open_and_read, &impl->open_and.read);
- }
-
- // read it
- return tb_aicp_ssl_read(ssl, data, size, func, priv);
-}
-tb_bool_t tb_aicp_ssl_open_writ(tb_aicp_ssl_ref_t ssl, tb_byte_t const* data, tb_size_t size, tb_aicp_ssl_writ_func_t func, tb_cpointer_t priv)
-{
- // check
- tb_aicp_ssl_impl_t* impl = (tb_aicp_ssl_impl_t*)ssl;
- tb_assert_and_check_return_val(impl && data && size && func, tb_false);
-
- // not opened? open it first
- if (TB_STATE_CLOSED == tb_atomic_get(&impl->state))
- {
- impl->open_and.writ.func = func;
- impl->open_and.writ.data = data;
- impl->open_and.writ.size = size;
- impl->open_and.writ.priv = priv;
- return tb_aicp_ssl_open(ssl, tb_aicp_ssl_open_and_writ, &impl->open_and.writ);
- }
-
- // writ it
- return tb_aicp_ssl_writ(ssl, data, size, func, priv);
-}
-tb_aicp_ref_t tb_aicp_ssl_aicp(tb_aicp_ssl_ref_t ssl)
-{
- // check
- tb_aicp_ssl_impl_t* impl = (tb_aicp_ssl_impl_t*)ssl;
- tb_assert_and_check_return_val(impl, tb_null);
-
- // the aicp
- return impl->aicp;
-}
-
diff --git a/core/src/tbox/src/tbox/asio/deprecated/ssl.h b/core/src/tbox/src/tbox/asio/deprecated/ssl.h
deleted file mode 100644
index b14a56df0..000000000
--- a/core/src/tbox/src/tbox/asio/deprecated/ssl.h
+++ /dev/null
@@ -1,287 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file ssl.h
- * @ingroup asio
- *
- */
-#ifndef TB_ASIO_SSL_H
-#define TB_ASIO_SSL_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "aicp.h"
-#include "../../network/ssl.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the aicp ssl ref type
-typedef __tb_typeref__(aicp_ssl);
-
-/*! the aicp ssl open func type
- *
- * @param ssl the ssl
- * @param state the state
- * @param priv the func private data
- *
- * @return tb_true: ok, tb_false: error, but not break aicp
- */
-typedef tb_bool_t (*tb_aicp_ssl_open_func_t)(tb_aicp_ssl_ref_t ssl, tb_size_t state, tb_cpointer_t priv);
-
-/*! the aicp ssl clos func type
- *
- * @param ssl the ssl
- * @param state the state
- * @param priv the func private data
- */
-typedef tb_void_t (*tb_aicp_ssl_clos_func_t)(tb_aicp_ssl_ref_t ssl, tb_size_t state, tb_cpointer_t priv);
-
-/*! the aicp ssl read func type
- *
- * @param ssl the ssl
- * @param state the state
- * @param data the readed data
- * @param real the real size, maybe zero
- * @param size the need size
- * @param priv the func private data
- *
- * @return tb_true: ok and continue it if need, tb_false: break it, but not break aicp
- */
-typedef tb_bool_t (*tb_aicp_ssl_read_func_t)(tb_aicp_ssl_ref_t ssl, tb_size_t state, tb_byte_t* data, tb_size_t real, tb_size_t size, tb_cpointer_t priv);
-
-/*! the aicp ssl writ func type
- *
- * @param ssl the ssl
- * @param state the state
- * @param data the writed data
- * @param real the real size, maybe zero
- * @param size the need size
- * @param priv the func private data
- *
- * @return tb_true: ok and continue it if need, tb_false: break it, but not break aicp
- */
-typedef tb_bool_t (*tb_aicp_ssl_writ_func_t)(tb_aicp_ssl_ref_t ssl, tb_size_t state, tb_byte_t const* data, tb_size_t real, tb_size_t size, tb_cpointer_t priv);
-
-/*! the aicp ssl task func type
- *
- * @param ssl the ssl
- * @param state the state
- * @param delay the delay
- * @param priv the func private data
- *
- * @return tb_true: ok, tb_false: error, but not break aicp
- */
-typedef tb_bool_t (*tb_aicp_ssl_task_func_t)(tb_aicp_ssl_ref_t ssl, tb_size_t state, tb_size_t delay, tb_cpointer_t priv);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init the ssl
- *
- * @param aicp the aicp
- * @param bserver is server endpoint?
- *
- * @return the ssl
- */
-__tb_deprecated__
-tb_aicp_ssl_ref_t tb_aicp_ssl_init(tb_aicp_ref_t aicp, tb_bool_t bserver);
-
-/*! kill the ssl
- *
- * @param ssl the ssl
- */
-__tb_deprecated__
-tb_void_t tb_aicp_ssl_kill(tb_aicp_ssl_ref_t ssl);
-
-/*! exit the ssl
- *
- * @param ssl the ssl
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_ssl_exit(tb_aicp_ssl_ref_t ssl);
-
-/*! set the ssl aico
- *
- * @param ssl the ssl
- * @param aico the aico
- */
-__tb_deprecated__
-tb_void_t tb_aicp_ssl_set_aico(tb_aicp_ssl_ref_t ssl, tb_aico_ref_t aico);
-
-/*! set the ssl timeout
- *
- * @param ssl the ssl
- * @param timeout the ssl timeout, using the default timeout if be zero
- */
-__tb_deprecated__
-tb_void_t tb_aicp_ssl_set_timeout(tb_aicp_ssl_ref_t ssl, tb_long_t timeout);
-
-/*! open the ssl
- *
- * @param ssl the ssl
- * @param func the func
- * @param priv the func data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_ssl_open(tb_aicp_ssl_ref_t ssl, tb_aicp_ssl_open_func_t func, tb_cpointer_t priv);
-
-/*! close the ssl
- *
- * @param handle the ssl
- * @param func the func
- * @param priv the func private data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_ssl_clos(tb_aicp_ssl_ref_t ssl, tb_aicp_ssl_clos_func_t func, tb_cpointer_t priv);
-
-/*! try closing the ssl
- *
- * @param ssl the ssl
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_ssl_clos_try(tb_aicp_ssl_ref_t ssl);
-
-/*! read the ssl
- *
- * @param ssl the ssl
- * @param data the read data
- * @param size the read size
- * @param func the func
- * @param priv the func data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_ssl_read(tb_aicp_ssl_ref_t ssl, tb_byte_t* data, tb_size_t size, tb_aicp_ssl_read_func_t func, tb_cpointer_t priv);
-
-/*! writ the ssl
- *
- * @param ssl the ssl
- * @param data the data
- * @param size the size
- * @param func the func
- * @param priv the func data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_ssl_writ(tb_aicp_ssl_ref_t ssl, tb_byte_t const* data, tb_size_t size, tb_aicp_ssl_writ_func_t func, tb_cpointer_t priv);
-
-/*! read the ssl after the delay time
- *
- * @param ssl the ssl
- * @param delay the delay time, ms
- * @param data the read data
- * @param size the read size
- * @param func the func
- * @param priv the func data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_ssl_read_after(tb_aicp_ssl_ref_t ssl, tb_size_t delay, tb_byte_t* data, tb_size_t size, tb_aicp_ssl_read_func_t func, tb_cpointer_t priv);
-
-/*! writ the ssl after the delay time
- *
- * @param ssl the ssl
- * @param delay the delay time, ms
- * @param data the data
- * @param size the size
- * @param func the func
- * @param priv the func data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_ssl_writ_after(tb_aicp_ssl_ref_t ssl, tb_size_t delay, tb_byte_t const* data, tb_size_t size, tb_aicp_ssl_writ_func_t func, tb_cpointer_t priv);
-
-/*! task the ssl
- *
- * @param ssl the ssl
- * @param delay the delay time, ms
- * @param func the func
- * @param priv the func data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_ssl_task(tb_aicp_ssl_ref_t ssl, tb_size_t delay, tb_aicp_ssl_task_func_t func, tb_cpointer_t priv);
-
-/*! open and read the ssl, open it first if not opened
- *
- * @param ssl the ssl
- * @param data the read data
- * @param size the read size
- * @param func the func
- * @param priv the func data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_ssl_open_read(tb_aicp_ssl_ref_t ssl, tb_byte_t* data, tb_size_t size, tb_aicp_ssl_read_func_t func, tb_cpointer_t priv);
-
-/*! open and writ the ssl, open it first if not opened
- *
- * @param ssl the ssl
- * @param data the data
- * @param size the size
- * @param func the func
- * @param priv the func data
- *
- * @return tb_true or tb_false
- */
-__tb_deprecated__
-tb_bool_t tb_aicp_ssl_open_writ(tb_aicp_ssl_ref_t ssl, tb_byte_t const* data, tb_size_t size, tb_aicp_ssl_writ_func_t func, tb_cpointer_t priv);
-
-/*! the ssl aicp
- *
- * @param ssl the ssl
- *
- * @return the aicp
- */
-__tb_deprecated__
-tb_aicp_ref_t tb_aicp_ssl_aicp(tb_aicp_ssl_ref_t ssl);
-
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/asio/prefix.h b/core/src/tbox/src/tbox/asio/prefix.h
deleted file mode 100644
index ee23c2646..000000000
--- a/core/src/tbox/src/tbox/asio/prefix.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file prefix.h
- *
- */
-#ifndef TB_ASIO_PREFIX_H
-#define TB_ASIO_PREFIX_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "../prefix.h"
-
-#endif
diff --git a/core/src/tbox/src/tbox/container/element/prefix.h b/core/src/tbox/src/tbox/container/element/prefix.h
index 7989dd5a6..27678adcb 100644
--- a/core/src/tbox/src/tbox/container/element/prefix.h
+++ b/core/src/tbox/src/tbox/container/element/prefix.h
@@ -33,7 +33,6 @@
#include "../../libc/libc.h"
#include "../../utils/utils.h"
#include "../../memory/memory.h"
-#include "../../object/object.h"
#include "../../stream/stream.h"
#include "../../platform/platform.h"
diff --git a/core/src/tbox/src/tbox/container/iterator/prefix.h b/core/src/tbox/src/tbox/container/iterator/prefix.h
index c5e0f98d2..2ba954c74 100644
--- a/core/src/tbox/src/tbox/container/iterator/prefix.h
+++ b/core/src/tbox/src/tbox/container/iterator/prefix.h
@@ -33,7 +33,6 @@
#include "../../libc/libc.h"
#include "../../utils/utils.h"
#include "../../memory/memory.h"
-#include "../../object/object.h"
#include "../../platform/platform.h"
diff --git a/core/src/tbox/src/tbox/coroutine/channel.c b/core/src/tbox/src/tbox/coroutine/channel.c
deleted file mode 100644
index 1a1dd82a8..000000000
--- a/core/src/tbox/src/tbox/coroutine/channel.c
+++ /dev/null
@@ -1,487 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file channel.h
- * @ingroup coroutine
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "channel"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "channel.h"
-#include "coroutine.h"
-#include "scheduler.h"
-#include "impl/impl.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/* the channel queue type
- *
- * we do not use tb_circle_queue_t because it is too heavy
- */
-typedef struct __tb_co_channel_queue_t
-{
- // the data
- tb_cpointer_t* data;
-
- // the head
- tb_size_t head;
-
- // the tail
- tb_size_t tail;
-
- // the maxn
- tb_size_t maxn;
-
- // the size
- tb_size_t size;
-
-}tb_co_channel_queue_t;
-
-// the coroutine channel type
-typedef struct __tb_co_channel_t
-{
- // the queue
- tb_co_channel_queue_t queue;
-
- // the free function
- tb_co_channel_free_func_t free;
-
- // the user private data
- tb_cpointer_t priv;
-
- // the waiting send coroutines
- tb_single_list_entry_head_t waiting_send;
-
- // the waiting recv coroutines
- tb_single_list_entry_head_t waiting_recv;
-
-}tb_co_channel_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * private implementation
- */
-static tb_bool_t tb_co_channel_send_resume(tb_co_channel_t* channel, tb_pointer_t* pdata)
-{
- // check
- tb_assert(channel);
-
- // resume the first waiting send coroutine and recv data
- tb_bool_t ok = tb_false;
- if (tb_single_list_entry_size(&channel->waiting_send))
- {
- // get the next entry from head
- tb_single_list_entry_ref_t entry = tb_single_list_entry_head(&channel->waiting_send);
- tb_assert(entry);
-
- // remove it from the waiting send coroutines
- tb_single_list_entry_remove_head(&channel->waiting_send);
-
- // get the waiting send coroutine
- tb_coroutine_ref_t waiting = (tb_coroutine_ref_t)tb_single_list_entry(&channel->waiting_send, entry);
-
- // resume this coroutine and recv data
- tb_pointer_t data = tb_coroutine_resume(waiting, tb_null);
-
- // save data
- if (pdata) *pdata = data;
-
- // ok
- ok = tb_true;
- }
-
- // ok?
- return ok;
-}
-static tb_void_t tb_co_channel_recv_resume(tb_co_channel_t* channel)
-{
- // check
- tb_assert(channel);
-
- // resume the first waiting recv coroutine
- if (tb_single_list_entry_size(&channel->waiting_recv))
- {
- // get the next entry from head
- tb_single_list_entry_ref_t entry = tb_single_list_entry_head(&channel->waiting_recv);
- tb_assert(entry);
-
- // remove it from the waiting recv coroutines
- tb_single_list_entry_remove_head(&channel->waiting_recv);
-
- // get the waiting recv coroutine
- tb_coroutine_ref_t waiting = (tb_coroutine_ref_t)tb_single_list_entry(&channel->waiting_recv, entry);
-
- // resume this coroutine
- tb_coroutine_resume(waiting, tb_null);
- }
-}
-static tb_void_t tb_co_channel_send_suspend(tb_co_channel_t* channel, tb_cpointer_t data)
-{
- // check
- tb_assert(channel);
-
- // get the running coroutine
- tb_coroutine_t* running = (tb_coroutine_t*)tb_coroutine_self();
- tb_assert(running);
-
- // save this coroutine to the waiting send coroutines
- tb_single_list_entry_insert_tail(&channel->waiting_send, &running->rs.single_entry);
-
- // send data and wait it
- tb_coroutine_suspend(data);
-}
-static tb_void_t tb_co_channel_recv_suspend(tb_co_channel_t* channel)
-{
- // check
- tb_assert(channel);
-
- // get the running coroutine
- tb_coroutine_t* running = (tb_coroutine_t*)tb_coroutine_self();
- tb_assert(running);
-
- // save this coroutine to the waiting recv coroutines
- tb_single_list_entry_insert_tail(&channel->waiting_recv, &running->rs.single_entry);
-
- // wait data
- tb_coroutine_suspend(tb_null);
-}
-static tb_void_t tb_co_channel_send_buffer(tb_co_channel_t* channel, tb_cpointer_t data)
-{
- // check
- tb_assert_and_check_return(channel && channel->queue.data);
-
- // done
- do
- {
- // put data into queue if be not full
- if (channel->queue.size + 1 < channel->queue.maxn)
- {
- // trace
- tb_trace_d("send[%p]: put data(%p)", tb_coroutine_self(), data);
-
- // put data
- channel->queue.data[channel->queue.tail] = data;
- channel->queue.tail = (channel->queue.tail + 1) % channel->queue.maxn;
- channel->queue.size++;
-
- // notify to recv data
- tb_co_channel_recv_resume(channel);
-
- // send ok
- break;
- }
- // wait it if be full
- else
- {
- // trace
- tb_trace_d("send[%p]: wait ..", tb_coroutine_self());
-
- // wait send
- tb_co_channel_send_suspend(channel, tb_null);
-
- // trace
- tb_trace_d("send[%p]: wait ok", tb_coroutine_self());
- }
-
- } while (1);
-
- // trace
- tb_trace_d("send[%p]: ok", tb_coroutine_self());
-}
-static tb_pointer_t tb_co_channel_recv_buffer(tb_co_channel_t* channel)
-{
- // check
- tb_assert_and_check_return_val(channel && channel->queue.data, tb_null);
-
- // done
- tb_pointer_t data = tb_null;
- do
- {
- // recv data from channel if be not null
- if (channel->queue.size)
- {
- // get data
- data = (tb_pointer_t)channel->queue.data[channel->queue.head];
-
- // pop data
- channel->queue.head = (channel->queue.head + 1) % channel->queue.maxn;
- channel->queue.size--;
-
- // trace
- tb_trace_d("recv[%p]: get data(%p)", tb_coroutine_self(), data);
-
- // notify to send data
- tb_co_channel_send_resume(channel, tb_null);
-
- // recv ok
- break;
- }
- // wait it if be null
- else
- {
- // trace
- tb_trace_d("recv[%p]: wait ..", tb_coroutine_self());
-
- // wait recv
- tb_co_channel_recv_suspend(channel);
-
- // trace
- tb_trace_d("recv[%p]: wait ok", tb_coroutine_self());
- }
-
- } while (1);
-
- // trace
- tb_trace_d("recv[%p]: ok", tb_coroutine_self());
-
- // get data
- return data;
-}
-static tb_bool_t tb_co_channel_send_buffer_try(tb_co_channel_t* channel, tb_cpointer_t data)
-{
- // check
- tb_assert_and_check_return_val(channel && channel->queue.data, tb_false);
-
- // put data into queue if be not full
- if (channel->queue.size + 1 < channel->queue.maxn)
- {
- // trace
- tb_trace_d("send[%p]: put data(%p)", tb_coroutine_self(), data);
-
- // put data
- channel->queue.data[channel->queue.tail] = data;
- channel->queue.tail = (channel->queue.tail + 1) % channel->queue.maxn;
- channel->queue.size++;
-
- // notify to recv data
- tb_co_channel_recv_resume(channel);
-
- // send ok
- return tb_true;
- }
-
- // failed
- return tb_false;
-}
-static tb_bool_t tb_co_channel_recv_buffer_try(tb_co_channel_t* channel, tb_pointer_t* pdata)
-{
- // check
- tb_assert_and_check_return_val(channel && channel->queue.data && pdata, tb_false);
-
- // recv data from channel if be not null
- if (channel->queue.size)
- {
- // get data
- *pdata = (tb_pointer_t)channel->queue.data[channel->queue.head];
-
- // pop data
- channel->queue.head = (channel->queue.head + 1) % channel->queue.maxn;
- channel->queue.size--;
-
- // trace
- tb_trace_d("recv[%p]: get data(%p)", tb_coroutine_self(), *pdata);
-
- // notify to send data
- tb_co_channel_send_resume(channel, tb_null);
-
- // recv ok
- return tb_true;
- }
-
- // failed
- return tb_false;
-}
-static tb_void_t tb_co_channel_send_buffer0(tb_co_channel_t* channel, tb_cpointer_t data)
-{
- // check
- tb_assert(channel);
-
- // resume one waiting recv coroutine
- tb_co_channel_recv_resume(channel);
-
- // send data and wait it
- tb_co_channel_send_suspend(channel, data);
-}
-static tb_pointer_t tb_co_channel_recv_buffer0(tb_co_channel_t* channel)
-{
- // check
- tb_assert(channel);
-
- // done
- tb_pointer_t data = tb_null;
- do
- {
- // resume the first waiting send coroutine and recv data
- if (tb_co_channel_send_resume(channel, &data))
- {
- // recv ok
- break;
- }
- // no data?
- else
- {
- // wait data
- tb_co_channel_recv_suspend(channel);
- }
-
- } while (1);
-
- // ok?
- return data;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_co_channel_ref_t tb_co_channel_init(tb_size_t size, tb_co_channel_free_func_t free, tb_cpointer_t priv)
-{
- // done
- tb_bool_t ok = tb_false;
- tb_co_channel_t* channel = tb_null;
- do
- {
- // make channel
- channel = tb_malloc0_type(tb_co_channel_t);
- tb_assert_and_check_break(channel);
-
- // init waiting send coroutines
- tb_single_list_entry_init(&channel->waiting_send, tb_coroutine_t, rs.single_entry, tb_null);
-
- // init waiting recv coroutines
- tb_single_list_entry_init(&channel->waiting_recv, tb_coroutine_t, rs.single_entry, tb_null);
-
- // init free function and data
- channel->free = free;
- channel->priv = priv;
-
- // with buffer?
- if (size)
- {
- // init maxn, + tail
- channel->queue.maxn = size + 1;
-
- // make data
- channel->queue.data = tb_nalloc_type(channel->queue.maxn, tb_cpointer_t);
- tb_assert_and_check_break(channel->queue.data);
- }
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (channel) tb_co_channel_exit((tb_co_channel_ref_t)channel);
- channel = tb_null;
- }
-
- // ok?
- return (tb_co_channel_ref_t)channel;
-}
-tb_void_t tb_co_channel_exit(tb_co_channel_ref_t self)
-{
- // check
- tb_co_channel_t* channel = (tb_co_channel_t*)self;
- tb_assert_and_check_return(channel);
-
- // exit queue
- if (channel->queue.data)
- {
- // free data
- if (channel->free)
- {
- tb_size_t head = channel->queue.head;
- tb_size_t maxn = channel->queue.maxn;
- tb_size_t size = channel->queue.size;
- while (size--)
- {
- channel->free((tb_pointer_t)channel->queue.data[head], channel->priv);
- head = (head + 1) % maxn;
- }
- }
-
- // free it
- tb_free(channel->queue.data);
- }
- channel->queue.data = tb_null;
- channel->queue.size = 0;
-
- // check waiting coroutines
- tb_assert(!tb_single_list_entry_size(&channel->waiting_send));
- tb_assert(!tb_single_list_entry_size(&channel->waiting_recv));
-
- // exit waiting coroutines
- tb_single_list_entry_exit(&channel->waiting_send);
- tb_single_list_entry_exit(&channel->waiting_recv);
-
- // exit the channel
- tb_free(channel);
-}
-tb_void_t tb_co_channel_send(tb_co_channel_ref_t self, tb_cpointer_t data)
-{
- // check
- tb_co_channel_t* channel = (tb_co_channel_t*)self;
- tb_assert_and_check_return(channel);
-
- // send it
- if (channel->queue.data) tb_co_channel_send_buffer(channel, data);
- else tb_co_channel_send_buffer0(channel, data);
-}
-tb_pointer_t tb_co_channel_recv(tb_co_channel_ref_t self)
-{
- // check
- tb_co_channel_t* channel = (tb_co_channel_t*)self;
- tb_assert_and_check_return_val(channel, tb_null);
-
- // recv it
- return channel->queue.data? tb_co_channel_recv_buffer(channel) : tb_co_channel_recv_buffer0(channel);
-}
-tb_bool_t tb_co_channel_send_try(tb_co_channel_ref_t self, tb_cpointer_t data)
-{
- // check
- tb_co_channel_t* channel = (tb_co_channel_t*)self;
- tb_assert_and_check_return_val(channel, tb_false);
-
- // try sending it
- return channel->queue.data? tb_co_channel_send_buffer_try(channel, data) : tb_false;
-}
-tb_bool_t tb_co_channel_recv_try(tb_co_channel_ref_t self, tb_pointer_t* pdata)
-{
- // check
- tb_co_channel_t* channel = (tb_co_channel_t*)self;
- tb_assert_and_check_return_val(channel && pdata, tb_false);
-
- // try recving it
- return channel->queue.data? tb_co_channel_recv_buffer_try(channel, pdata) : tb_false;
-}
-
diff --git a/core/src/tbox/src/tbox/coroutine/channel.h b/core/src/tbox/src/tbox/coroutine/channel.h
deleted file mode 100644
index c5b6c0749..000000000
--- a/core/src/tbox/src/tbox/coroutine/channel.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file channel.h
- * @ingroup coroutine
- *
- */
-#ifndef TB_COROUTINE_CHANNEL_H
-#define TB_COROUTINE_CHANNEL_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-#include "../container/container.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the coroutine channel ref type
-typedef __tb_typeref__(co_channel);
-
-/*! the free function type
- *
- * @param data the channel data
- * @param priv the user private data
- */
-typedef tb_void_t (*tb_co_channel_free_func_t)(tb_pointer_t data, tb_cpointer_t priv);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init channel
- *
- * @param size the buffer size, 0: no buffer
- * @param free the free function
- * @param priv the user private data
- *
- * @return the channel
- */
-tb_co_channel_ref_t tb_co_channel_init(tb_size_t size, tb_co_channel_free_func_t free, tb_cpointer_t priv);
-
-/*! exit channel
- *
- * @param channel the channel
- */
-tb_void_t tb_co_channel_exit(tb_co_channel_ref_t channel);
-
-/*! send data into channel
- *
- * the current coroutine will be suspend if this channel is full
- *
- * @param channel the channel
- * @param data the channel data
- */
-tb_void_t tb_co_channel_send(tb_co_channel_ref_t channel, tb_cpointer_t data);
-
-/*! recv data from channel
- *
- * the current coroutine will be suspend if no data
- *
- * @param channel the channel
- *
- * @return the channel data
- */
-tb_pointer_t tb_co_channel_recv(tb_co_channel_ref_t channel);
-
-/*! try sending data into channel only with buffer
- *
- * the current coroutine will be suspend if this channel is full
- *
- * @param channel the channel
- * @param data the channel data
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_co_channel_send_try(tb_co_channel_ref_t channel, tb_cpointer_t data);
-
-/*! try recving data from channel only with buffer
- *
- * the current coroutine will be suspend if no data
- *
- * @param channel the channel
- * @param pdata the channel data pointer
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_co_channel_recv_try(tb_co_channel_ref_t channel, tb_pointer_t* pdata);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/coroutine/coroutine.c b/core/src/tbox/src/tbox/coroutine/coroutine.c
deleted file mode 100644
index b5b863ea3..000000000
--- a/core/src/tbox/src/tbox/coroutine/coroutine.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file coroutine.h
- * @ingroup coroutine
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "coroutine"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "coroutine.h"
-#include "scheduler.h"
-#include "impl/impl.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_bool_t tb_coroutine_start(tb_co_scheduler_ref_t scheduler, tb_coroutine_func_t func, tb_cpointer_t priv, tb_size_t stacksize)
-{
- // check
- tb_assert_and_check_return_val(func, tb_false);
-
- // start it
- return tb_co_scheduler_start((tb_co_scheduler_t*)scheduler, func, priv, stacksize);
-}
-tb_bool_t tb_coroutine_yield()
-{
- // get current scheduler
- tb_co_scheduler_t* scheduler = (tb_co_scheduler_t*)tb_co_scheduler_self();
-
- // yield the current coroutine
- return scheduler? tb_co_scheduler_yield(scheduler) : tb_false;
-}
-tb_pointer_t tb_coroutine_resume(tb_coroutine_ref_t coroutine, tb_cpointer_t priv)
-{
- // get current scheduler
- tb_co_scheduler_t* scheduler = (tb_co_scheduler_t*)tb_co_scheduler_self();
-
- // resume the given coroutine
- return scheduler? tb_co_scheduler_resume(scheduler, (tb_coroutine_t*)coroutine, priv) : tb_null;
-}
-tb_pointer_t tb_coroutine_suspend(tb_cpointer_t priv)
-{
- // get current scheduler
- tb_co_scheduler_t* scheduler = (tb_co_scheduler_t*)tb_co_scheduler_self();
-
- // suspend the current coroutine
- return scheduler? tb_co_scheduler_suspend(scheduler, priv) : tb_null;
-}
-tb_pointer_t tb_coroutine_sleep(tb_long_t interval)
-{
- // get current scheduler
- tb_co_scheduler_t* scheduler = (tb_co_scheduler_t*)tb_co_scheduler_self();
-
- // sleep the current coroutine
- return scheduler? tb_co_scheduler_sleep(scheduler, interval) : tb_null;
-}
-tb_long_t tb_coroutine_waitio(tb_socket_ref_t sock, tb_size_t events, tb_long_t timeout)
-{
- // get current scheduler
- tb_co_scheduler_t* scheduler = (tb_co_scheduler_t*)tb_co_scheduler_self();
-
- // wait events
- return scheduler? tb_co_scheduler_wait(scheduler, sock, events, timeout) : -1;
-}
-tb_coroutine_ref_t tb_coroutine_self()
-{
- // get coroutine
- tb_co_scheduler_t* scheduler = (tb_co_scheduler_t*)tb_co_scheduler_self();
-
- // get running coroutine
- return scheduler? (tb_coroutine_ref_t)tb_co_scheduler_running(scheduler) : tb_null;
-}
-
diff --git a/core/src/tbox/src/tbox/coroutine/coroutine.h b/core/src/tbox/src/tbox/coroutine/coroutine.h
deleted file mode 100644
index 7bdc33d82..000000000
--- a/core/src/tbox/src/tbox/coroutine/coroutine.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file coroutine.h
- * @defgroup coroutine
- *
- */
-#ifndef TB_COROUTINE_H
-#define TB_COROUTINE_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "lock.h"
-#include "channel.h"
-#include "semaphore.h"
-#include "scheduler.h"
-#include "stackless/stackless.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the coroutine ref type
-typedef __tb_typeref__(coroutine);
-
-/// the coroutine function type
-typedef tb_void_t (*tb_coroutine_func_t)(tb_cpointer_t priv);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! start coroutine
- *
- * @param scheduler the scheduler, uses the current scheduler if be null
- * @param func the coroutine function
- * @param priv the passed user private data as the argument of function
- * @param stacksize the stack size
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_coroutine_start(tb_co_scheduler_ref_t scheduler, tb_coroutine_func_t func, tb_cpointer_t priv, tb_size_t stacksize);
-
-/*! yield the current coroutine
- *
- * @return tb_true(yield ok) or tb_false(yield failed, no more coroutines)
- */
-tb_bool_t tb_coroutine_yield(tb_noarg_t);
-
-/*! resume the given coroutine (suspended)
- *
- * @param coroutine the suspended coroutine
- * @param priv the user private data as the return value of suspend() or sleep()
- *
- * @return the user private data from suspend(priv)
- */
-tb_pointer_t tb_coroutine_resume(tb_coroutine_ref_t coroutine, tb_cpointer_t priv);
-
-/*! suspend the current coroutine
- *
- * @param priv the user private data as the return value of resume()
- *
- * @return the user private data from resume(priv)
- */
-tb_pointer_t tb_coroutine_suspend(tb_cpointer_t priv);
-
-/*! sleep some times (ms)
- *
- * @param interval the interval (ms), infinity: -1
- *
- * @return the user private data from resume(priv)
- */
-tb_pointer_t tb_coroutine_sleep(tb_long_t interval);
-
-/*! wait io events
- *
- * @param sock the socket
- * @param events the waited events, will remove this socket from io scheduler if be TB_SOCKET_EVENT_NONE
- * @param timeout the timeout, infinity: -1
- *
- * @return > 0: the events, 0: timeout, -1: failed
- */
-tb_long_t tb_coroutine_waitio(tb_socket_ref_t sock, tb_size_t events, tb_long_t timeout);
-
-/*! get the current coroutine
- *
- * @return the current coroutine
- */
-tb_coroutine_ref_t tb_coroutine_self(tb_noarg_t);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/coroutine/impl/coroutine.c b/core/src/tbox/src/tbox/coroutine/impl/coroutine.c
deleted file mode 100644
index 3341d780c..000000000
--- a/core/src/tbox/src/tbox/coroutine/impl/coroutine.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file coroutine.h
- * @ingroup coroutine
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "coroutine"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "coroutine.h"
-#include "scheduler.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-// the stack guard magic
-#define TB_COROUTINE_STACK_GUARD (0xbeef)
-
-// the default stack size
-#define TB_COROUTINE_STACK_DEFSIZE (8192 << 1)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static tb_void_t tb_coroutine_entry(tb_context_from_t from)
-{
- // get the from-coroutine
- tb_coroutine_t* coroutine_from = (tb_coroutine_t*)from.priv;
- tb_assert(coroutine_from && from.context);
-
- // update the context
- coroutine_from->context = from.context;
- tb_assert(from.context);
-
- // get the current coroutine
- tb_coroutine_t* coroutine = (tb_coroutine_t*)tb_coroutine_self();
- tb_assert(coroutine);
-
-#ifdef __tb_debug__
- // check it
- tb_coroutine_check(coroutine);
-#endif
-
- // trace
- tb_trace_d("entry: %p stack: %p - %p from coroutine(%p)", coroutine, coroutine->stackbase - coroutine->stacksize, coroutine->stackbase, coroutine_from);
-
- // get function and private data
- tb_coroutine_func_t func = coroutine->rs.func.func;
- tb_cpointer_t priv = coroutine->rs.func.priv;
- tb_assert(func);
-
- // reset rs data first for waiting io
- tb_memset(&coroutine->rs, 0, sizeof(coroutine->rs));
-
- // call the coroutine function
- func(priv);
-
- // finish the current coroutine and switch to the other coroutine
- tb_co_scheduler_finish((tb_co_scheduler_t*)tb_co_scheduler_self());
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_coroutine_t* tb_coroutine_init(tb_co_scheduler_ref_t scheduler, tb_coroutine_func_t func, tb_cpointer_t priv, tb_size_t stacksize)
-{
- // check
- tb_assert_and_check_return_val(scheduler && func, tb_null);
-
- // done
- tb_bool_t ok = tb_false;
- tb_coroutine_t* coroutine = tb_null;
- do
- {
- // init stack size
- if (!stacksize) stacksize = TB_COROUTINE_STACK_DEFSIZE;
-
-#ifdef __tb_debug__
- // patch debug stack size for (assert, trace ..)
- stacksize <<= 1;
-#endif
-
- /* make coroutine
- *
- * TODO:
- *
- * - segment stack
- *
- * -----------------------------------------------
- * | coroutine | guard | ... stacksize ... | guard |
- * -----------------------------------------------
- */
- coroutine = (tb_coroutine_t*)tb_malloc_bytes(sizeof(tb_coroutine_t) + stacksize + sizeof(tb_uint16_t));
- tb_assert_and_check_break(coroutine);
-
- // save scheduler
- coroutine->scheduler = scheduler;
-
- // init stack
- coroutine->stackbase = (tb_byte_t*)&(coroutine[1]) + stacksize;
- coroutine->stacksize = stacksize;
-
- // fill guard
- coroutine->guard = TB_COROUTINE_STACK_GUARD;
- tb_bits_set_u16_ne(coroutine->stackbase, TB_COROUTINE_STACK_GUARD);
-
- // init function and user private data
- coroutine->rs.func.func = func;
- coroutine->rs.func.priv = priv;
-
- // make context
- coroutine->context = tb_context_make(coroutine->stackbase - stacksize, stacksize, tb_coroutine_entry);
- tb_assert_and_check_break(coroutine->context);
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (coroutine) tb_coroutine_exit(coroutine);
- coroutine = tb_null;
- }
-
- // trace
- tb_trace_d("init %p", coroutine);
-
- // ok?
- return coroutine;
-}
-tb_coroutine_t* tb_coroutine_reinit(tb_coroutine_t* coroutine, tb_coroutine_func_t func, tb_cpointer_t priv, tb_size_t stacksize)
-{
- // check
- tb_assert_and_check_return_val(coroutine && func, tb_null);
-
- // done
- tb_bool_t ok = tb_false;
- do
- {
- // init stack size
- if (!stacksize) stacksize = TB_COROUTINE_STACK_DEFSIZE;
-
-#ifdef __tb_debug__
- // patch debug stack size for (assert, trace ..)
- stacksize <<= 1;
-
- // check coroutine
- tb_coroutine_check(coroutine);
-#endif
-
- // remake coroutine
- if (stacksize > coroutine->stacksize)
- coroutine = (tb_coroutine_t*)tb_ralloc_bytes(coroutine, sizeof(tb_coroutine_t) + stacksize + sizeof(tb_uint16_t));
- else stacksize = coroutine->stacksize;
- tb_assert_and_check_break(coroutine && coroutine->scheduler);
-
- // init stack
- coroutine->stackbase = (tb_byte_t*)&(coroutine[1]) + stacksize;
- coroutine->stacksize = stacksize;
-
- // fill guard
- coroutine->guard = TB_COROUTINE_STACK_GUARD;
- tb_bits_set_u16_ne(coroutine->stackbase, TB_COROUTINE_STACK_GUARD);
-
- // init function and user private data
- coroutine->rs.func.func = func;
- coroutine->rs.func.priv = priv;
-
- // make context
- coroutine->context = tb_context_make(coroutine->stackbase - stacksize, stacksize, tb_coroutine_entry);
- tb_assert_and_check_break(coroutine->context);
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed? reset it
- if (!ok) coroutine = tb_null;
-
- // trace
- tb_trace_d("reinit %p", coroutine);
-
- // ok?
- return coroutine;
-}
-tb_void_t tb_coroutine_exit(tb_coroutine_t* coroutine)
-{
- // check
- tb_assert_and_check_return(coroutine);
-
- // trace
- tb_trace_d("exit: %p", coroutine);
-
-#ifdef __tb_debug__
- // check it
- tb_coroutine_check(coroutine);
-#endif
-
- // exit it
- tb_free(coroutine);
-}
-#ifdef __tb_debug__
-tb_void_t tb_coroutine_check(tb_coroutine_t* coroutine)
-{
- // check
- tb_assert(coroutine && coroutine->context);
-
- // this coroutine is original for scheduler?
- tb_check_return(!tb_coroutine_is_original(coroutine));
-
- // check stack underflow
- if (coroutine->guard != TB_COROUTINE_STACK_GUARD)
- {
- // trace
- tb_trace_e("this coroutine stack is underflow!");
-
- // dump stack
- tb_dump_data(coroutine->stackbase - coroutine->stacksize, coroutine->stacksize);
-
- // abort
- tb_abort();
- }
-
- // check stack overflow
- if (tb_bits_get_u16_ne(coroutine->stackbase) != TB_COROUTINE_STACK_GUARD)
- {
- // trace
- tb_trace_e("this coroutine stack is overflow!");
-
- // dump stack
- tb_dump_data(coroutine->stackbase - coroutine->stacksize, coroutine->stacksize);
-
- // abort
- tb_abort();
- }
-}
-#endif
-
diff --git a/core/src/tbox/src/tbox/coroutine/impl/coroutine.h b/core/src/tbox/src/tbox/coroutine/impl/coroutine.h
deleted file mode 100644
index ae27d74bf..000000000
--- a/core/src/tbox/src/tbox/coroutine/impl/coroutine.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file coroutine.h
- * @ingroup coroutine
- *
- */
-#ifndef TB_COROUTINE_IMPL_COROUTINE_H
-#define TB_COROUTINE_IMPL_COROUTINE_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-// get scheduler
-#define tb_coroutine_scheduler(coroutine) ((coroutine)->scheduler)
-
-// is original?
-#define tb_coroutine_is_original(coroutine) ((coroutine)->scheduler == (tb_co_scheduler_ref_t)(coroutine))
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the coroutine function type
-typedef struct __tb_coroutine_rs_func_t
-{
- // the function
- tb_coroutine_func_t func;
-
- // the user private data as the argument of function
- tb_cpointer_t priv;
-
-}tb_coroutine_rs_func_t;
-
-// the coroutine wait type
-typedef struct __tb_coroutine_rs_wait_t
-{
- /* the timer task pointer for ltimer or timer
- *
- * for ltimer: task
- * for timer: task & 0x1
- */
- tb_cpointer_t task;
-
- // the socket
- tb_socket_ref_t sock;
-
- // the waiting events
- tb_uint16_t events : 6;
-
- // the cached events
- tb_uint16_t events_cache : 6;
-
- // is waiting?
- tb_uint16_t waiting : 1;
-
-}tb_coroutine_rs_wait_t;
-
-// the coroutine type
-typedef struct __tb_coroutine_t
-{
- /* the list entry for ready, suspend and dead lists
- *
- * be placed in the head for optimization
- */
- tb_list_entry_t entry;
-
- // the scheduler
- tb_co_scheduler_ref_t scheduler;
-
- // the context
- tb_context_ref_t context;
-
- // the stack base (top)
- tb_byte_t* stackbase;
-
- // the stack size
- tb_size_t stacksize;
-
- // the passed user private data between priv = resume(priv) and priv = suspend(priv)
- tb_cpointer_t rs_priv;
-
- // the passed private data between resume() and suspend()
- union
- {
- // the function
- tb_coroutine_rs_func_t func;
-
- // the arguments for wait()
- tb_coroutine_rs_wait_t wait;
-
- // the list entry
- tb_list_entry_t entry;
-
- // the single entry
- tb_single_list_entry_t single_entry;
-
- } rs;
-
- // the guard
- tb_uint16_t guard;
-
-}tb_coroutine_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/* init coroutine
- *
- * @param scheduler the scheduler
- * @param func the coroutine function
- * @param priv the passed user private data as the argument of function
- * @param stacksize the stack size, uses the default stack size if be zero
- *
- * @return the coroutine
- */
-tb_coroutine_t* tb_coroutine_init(tb_co_scheduler_ref_t scheduler, tb_coroutine_func_t func, tb_cpointer_t priv, tb_size_t stacksize);
-
-/* reinit the given coroutine
- *
- * @param coroutine the coroutine
- * @param func the coroutine function
- * @param priv the passed user private data as the argument of function
- * @param stacksize the stack size, uses the default stack size if be zero
- *
- * @return the coroutine
- */
-tb_coroutine_t* tb_coroutine_reinit(tb_coroutine_t* coroutine, tb_coroutine_func_t func, tb_cpointer_t priv, tb_size_t stacksize);
-
-/* exit coroutine
- *
- * @param coroutine the coroutine
- */
-tb_void_t tb_coroutine_exit(tb_coroutine_t* coroutine);
-
-#ifdef __tb_debug__
-/* check coroutine
- *
- * @param coroutine the coroutine
- */
-tb_void_t tb_coroutine_check(tb_coroutine_t* coroutine);
-#endif
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/coroutine/impl/impl.h b/core/src/tbox/src/tbox/coroutine/impl/impl.h
deleted file mode 100644
index e3aeb366e..000000000
--- a/core/src/tbox/src/tbox/coroutine/impl/impl.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file impl.h
- *
- */
-#ifndef TB_COROUTINE_IMPL_H
-#define TB_COROUTINE_IMPL_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-#include "coroutine.h"
-#include "scheduler.h"
-#include "scheduler_io.h"
-#include "stackless/stackless.h"
-
-#endif
diff --git a/core/src/tbox/src/tbox/coroutine/impl/prefix.h b/core/src/tbox/src/tbox/coroutine/impl/prefix.h
deleted file mode 100644
index bc6835ca4..000000000
--- a/core/src/tbox/src/tbox/coroutine/impl/prefix.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file prefix.h
- *
- */
-#ifndef TB_COROUTINE_IMPL_PREFIX_H
-#define TB_COROUTINE_IMPL_PREFIX_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "../prefix.h"
-#include "../coroutine.h"
-#include "../../libc/libc.h"
-#include "../../utils/utils.h"
-#include "../../platform/platform.h"
-#include "../../container/container.h"
-
-
-#endif
diff --git a/core/src/tbox/src/tbox/coroutine/impl/scheduler.c b/core/src/tbox/src/tbox/coroutine/impl/scheduler.c
deleted file mode 100644
index 0653ca00a..000000000
--- a/core/src/tbox/src/tbox/coroutine/impl/scheduler.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file scheduler.c
- * @ingroup coroutine
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "scheduler"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "scheduler.h"
-#include "coroutine.h"
-#include "scheduler_io.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-// the dead cache maximum count
-#ifdef __tb_small__
-# define TB_SCHEDULER_DEAD_CACHE_MAXN (64)
-#else
-# define TB_SCHEDULER_DEAD_CACHE_MAXN (256)
-#endif
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * private implementation
- */
-static __tb_inline__ tb_bool_t tb_co_scheduler_need_io(tb_co_scheduler_t* scheduler)
-{
- // check
- tb_assert(scheduler);
-
- // init io scheduler first
- if (!scheduler->scheduler_io) scheduler->scheduler_io = tb_co_scheduler_io_init(scheduler);
- tb_assert(scheduler->scheduler_io);
-
- // ok?
- return scheduler->scheduler_io != tb_null;
-}
-static tb_void_t tb_co_scheduler_make_dead(tb_co_scheduler_t* scheduler, tb_coroutine_t* coroutine)
-{
- // check
- tb_assert(scheduler && coroutine);
-
- // cannot be original coroutine
- tb_assert(!tb_coroutine_is_original(coroutine));
-
- // remove this coroutine from the ready coroutines
- tb_list_entry_remove(&scheduler->coroutines_ready, (tb_list_entry_ref_t)coroutine);
-
- // append this coroutine to dead coroutines
- tb_list_entry_insert_tail(&scheduler->coroutines_dead, (tb_list_entry_ref_t)coroutine);
-}
-static tb_void_t tb_co_scheduler_make_ready(tb_co_scheduler_t* scheduler, tb_coroutine_t* coroutine)
-{
- // check
- tb_assert(scheduler && coroutine);
-
- // insert this coroutine to ready coroutines
- if (__tb_unlikely__(tb_coroutine_is_original(scheduler->running)))
- {
- // .. last -> coroutine(inserted)
- tb_list_entry_insert_tail(&scheduler->coroutines_ready, (tb_list_entry_ref_t)coroutine);
- }
- else
- {
- // .. -> coroutine(inserted) -> running -> ..
- tb_list_entry_insert_prev(&scheduler->coroutines_ready, (tb_list_entry_ref_t)scheduler->running, (tb_list_entry_ref_t)coroutine);
- }
-}
-static tb_void_t tb_co_scheduler_make_suspend(tb_co_scheduler_t* scheduler, tb_coroutine_t* coroutine)
-{
- // check
- tb_assert(scheduler && coroutine);
-
- // cannot be original coroutine
- tb_assert(!tb_coroutine_is_original(coroutine));
-
- // remove this coroutine from the ready coroutines
- tb_list_entry_remove(&scheduler->coroutines_ready, (tb_list_entry_ref_t)coroutine);
-
- // append this coroutine to suspend coroutines
- tb_list_entry_insert_tail(&scheduler->coroutines_suspend, (tb_list_entry_ref_t)coroutine);
-}
-static __tb_inline__ tb_coroutine_t* tb_co_scheduler_next_ready(tb_co_scheduler_t* scheduler)
-{
- // check
- tb_assert(scheduler && scheduler->running && tb_list_entry_size(&scheduler->coroutines_ready));
-
- // get the next entry
- tb_list_entry_ref_t entry_next = tb_list_entry_next((tb_list_entry_ref_t)scheduler->running);
- tb_assert(entry_next);
-
- // is list header? skip it and get the first entry
- if (entry_next == (tb_list_entry_ref_t)&scheduler->coroutines_ready)
- entry_next = tb_list_entry_next(entry_next);
-
- // get the next ready coroutine
- return (tb_coroutine_t*)tb_list_entry0(entry_next);
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_bool_t tb_co_scheduler_start(tb_co_scheduler_t* scheduler, tb_coroutine_func_t func, tb_cpointer_t priv, tb_size_t stacksize)
-{
- // check
- tb_assert(func);
-
- // done
- tb_bool_t ok = tb_false;
- tb_coroutine_t* coroutine = tb_null;
- do
- {
- // trace
- tb_trace_d("start ..");
-
- // uses the current scheduler if be null
- if (!scheduler) scheduler = (tb_co_scheduler_t*)tb_co_scheduler_self();
- tb_assert_and_check_break(scheduler);
-
- // have been stopped? do not continue to start new coroutines
- tb_check_break(!scheduler->stopped);
-
- // reuses dead coroutines in init function
- if (tb_list_entry_size(&scheduler->coroutines_dead))
- {
- // get the next entry from head
- tb_list_entry_ref_t entry = tb_list_entry_head(&scheduler->coroutines_dead);
- tb_assert_and_check_break(entry);
-
- // remove it from the ready coroutines
- tb_list_entry_remove_head(&scheduler->coroutines_dead);
-
- // get the dead coroutine
- tb_coroutine_t* coroutine_dead = (tb_coroutine_t*)tb_list_entry0(entry);
-
- // reinit this coroutine
- coroutine = tb_coroutine_reinit(coroutine_dead, func, priv, stacksize);
-
- // failed? exit this coroutine
- if (!coroutine) tb_coroutine_exit(coroutine_dead);
- }
-
- // init coroutine
- if (!coroutine) coroutine = tb_coroutine_init((tb_co_scheduler_ref_t)scheduler, func, priv, stacksize);
- tb_assert_and_check_break(coroutine);
-
- // ready coroutine
- tb_co_scheduler_make_ready(scheduler, coroutine);
-
- // the dead coroutines is too much? free some coroutines
- while (tb_list_entry_size(&scheduler->coroutines_dead) > TB_SCHEDULER_DEAD_CACHE_MAXN)
- {
- // get the next entry from head
- tb_list_entry_ref_t entry = tb_list_entry_head(&scheduler->coroutines_dead);
- tb_assert(entry);
-
- // remove it from the ready coroutines
- tb_list_entry_remove_head(&scheduler->coroutines_dead);
-
- // exit this coroutine
- tb_coroutine_exit((tb_coroutine_t*)tb_list_entry0(entry));
- }
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // trace
- tb_trace_d("start %s", ok? "ok" : "no");
-
- // ok?
- return ok;
-}
-tb_bool_t tb_co_scheduler_yield(tb_co_scheduler_t* scheduler)
-{
- // check
- tb_assert(scheduler && scheduler->running);
- tb_assert(scheduler->running == (tb_coroutine_t*)tb_coroutine_self());
-
- // trace
- tb_trace_d("yield coroutine(%p)", scheduler->running);
-
- // get the next ready coroutine
- tb_coroutine_t* coroutine_next = tb_co_scheduler_next_ready(scheduler);
- if (coroutine_next != scheduler->running)
- {
- // switch to the next coroutine
- tb_co_scheduler_switch(scheduler, coroutine_next);
-
- // ok
- return tb_true;
- }
- // no more coroutine (only running)?
- else
- {
- // trace
- tb_trace_d("continue to run current coroutine(%p)", tb_coroutine_self());
-
- // check
- tb_assert((tb_list_entry_ref_t)scheduler->running == tb_list_entry_head(&scheduler->coroutines_ready));
- }
-
- // return it directly and continue to run this coroutine
- return tb_false;
-}
-tb_pointer_t tb_co_scheduler_resume(tb_co_scheduler_t* scheduler, tb_coroutine_t* coroutine, tb_cpointer_t priv)
-{
- // check
- tb_assert(scheduler && coroutine);
-
- // trace
- tb_trace_d("resume coroutine(%p)", coroutine);
-
- // remove it from the suspend coroutines
- tb_list_entry_remove(&scheduler->coroutines_suspend, (tb_list_entry_ref_t)coroutine);
-
- // get the passed private data from suspend(priv)
- tb_pointer_t retval = (tb_pointer_t)coroutine->rs_priv;
-
- // pass the user private data to suspend()
- coroutine->rs_priv = priv;
-
- // make it as ready
- tb_co_scheduler_make_ready(scheduler, coroutine);
-
- // return it
- return retval;
-}
-tb_pointer_t tb_co_scheduler_suspend(tb_co_scheduler_t* scheduler, tb_cpointer_t priv)
-{
- // check
- tb_assert(scheduler && scheduler->running);
- tb_assert(scheduler->running == (tb_coroutine_t*)tb_coroutine_self());
-
- // have been stopped? return it directly
- tb_check_return_val(!scheduler->stopped, tb_null);
-
- // trace
- tb_trace_d("suspend coroutine(%p)", scheduler->running);
-
- // pass the private data to resume() first
- scheduler->running->rs_priv = priv;
-
- // get the next ready coroutine first
- tb_coroutine_t* coroutine_next = tb_co_scheduler_next_ready(scheduler);
-
- // make the running coroutine as suspend
- tb_co_scheduler_make_suspend(scheduler, scheduler->running);
-
- // switch to next coroutine
- if (coroutine_next != scheduler->running) tb_co_scheduler_switch(scheduler, coroutine_next);
- // no more coroutine?
- else
- {
- // trace
- tb_trace_d("switch to original coroutine");
-
- // switch to the original coroutine
- tb_co_scheduler_switch(scheduler, &scheduler->original);
- }
-
- // check
- tb_assert(scheduler->running);
-
- // return the user private data from resume(priv)
- return (tb_pointer_t)scheduler->running->rs_priv;
-}
-tb_void_t tb_co_scheduler_finish(tb_co_scheduler_t* scheduler)
-{
- // check
- tb_assert(scheduler && scheduler->running);
- tb_assert(scheduler->running == (tb_coroutine_t*)tb_coroutine_self());
-
- // trace
- tb_trace_d("finish coroutine(%p)", scheduler->running);
-
- // get the next ready coroutine first
- tb_coroutine_t* coroutine_next = tb_co_scheduler_next_ready(scheduler);
-
- // make the running coroutine as dead
- tb_co_scheduler_make_dead(scheduler, scheduler->running);
-
- // switch to next coroutine
- if (coroutine_next != scheduler->running) tb_co_scheduler_switch(scheduler, coroutine_next);
- // no more coroutine?
- else
- {
- // trace
- tb_trace_d("switch to original coroutine");
-
- // switch to the original coroutine
- tb_co_scheduler_switch(scheduler, &scheduler->original);
- }
-}
-tb_pointer_t tb_co_scheduler_sleep(tb_co_scheduler_t* scheduler, tb_long_t interval)
-{
- // check
- tb_assert(scheduler && scheduler->running);
- tb_assert(scheduler->running == (tb_coroutine_t*)tb_coroutine_self());
-
- // have been stopped? return it directly
- tb_check_return_val(!scheduler->stopped, tb_null);
-
- // need io scheduler
- if (!tb_co_scheduler_need_io(scheduler)) return tb_null;
-
- // sleep it
- return tb_co_scheduler_io_sleep(scheduler->scheduler_io, interval);
-}
-tb_void_t tb_co_scheduler_switch(tb_co_scheduler_t* scheduler, tb_coroutine_t* coroutine)
-{
- // check
- tb_assert(scheduler && scheduler->running);
- tb_assert(coroutine && coroutine->context);
-
- // the current running coroutine
- tb_coroutine_t* running = scheduler->running;
-
- // mark the given coroutine as running
- scheduler->running = coroutine;
-
- // trace
- tb_trace_d("switch to coroutine(%p) from coroutine(%p)", coroutine, running);
-
- // jump to the given coroutine
- tb_context_from_t from = tb_context_jump(coroutine->context, running);
-
- // the from-coroutine
- tb_coroutine_t* coroutine_from = (tb_coroutine_t*)from.priv;
- tb_assert(coroutine_from && from.context);
-
-#ifdef __tb_debug__
- // check it
- tb_coroutine_check(coroutine_from);
-#endif
-
- // update the context
- coroutine_from->context = from.context;
-}
-tb_long_t tb_co_scheduler_wait(tb_co_scheduler_t* scheduler, tb_socket_ref_t sock, tb_size_t events, tb_long_t timeout)
-{
- // check
- tb_assert(scheduler && scheduler->running);
- tb_assert(scheduler->running == (tb_coroutine_t*)tb_coroutine_self());
-
- // have been stopped? return it directly
- tb_check_return_val(!scheduler->stopped, -1);
-
- // need io scheduler
- if (!tb_co_scheduler_need_io(scheduler)) return -1;
-
- // sleep it
- return tb_co_scheduler_io_wait(scheduler->scheduler_io, sock, events, timeout);
-}
diff --git a/core/src/tbox/src/tbox/coroutine/impl/scheduler.h b/core/src/tbox/src/tbox/coroutine/impl/scheduler.h
deleted file mode 100644
index 98fa85d38..000000000
--- a/core/src/tbox/src/tbox/coroutine/impl/scheduler.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file scheduler.h
- * @ingroup coroutine
- *
- */
-#ifndef TB_COROUTINE_IMPL_SCHEDULER_H
-#define TB_COROUTINE_IMPL_SCHEDULER_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-#include "coroutine.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-// get the running coroutine
-#define tb_co_scheduler_running(scheduler) ((scheduler)->running)
-
-// get the ready coroutines count
-#define tb_co_scheduler_ready_count(scheduler) tb_list_entry_size(&(scheduler)->coroutines_ready)
-
-// get the suspended coroutines count
-#define tb_co_scheduler_suspend_count(scheduler) tb_list_entry_size(&(scheduler)->coroutines_suspend)
-
-// get the io scheduler
-#define tb_co_scheduler_io(scheduler) ((scheduler)->scheduler_io)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the io scheduler type
-struct __tb_co_scheduler_io_t;
-
-// the scheduler type
-typedef struct __tb_co_scheduler_t
-{
- /* the original coroutine (in main loop)
- *
- * coroutine->scheduler == (tb_co_scheduler_ref_t)coroutine
- */
- tb_coroutine_t original;
-
- // is stopped
- tb_bool_t stopped;
-
- // the running coroutine
- tb_coroutine_t* running;
-
- // the io scheduler
- struct __tb_co_scheduler_io_t* scheduler_io;
-
- // the dead coroutines
- tb_list_entry_head_t coroutines_dead;
-
- /* the ready coroutines
- *
- * ready: head -> ready -> .. -> running -> .. -> ready -> ..->
- * | |
- * ---------------------------<-----------------------
- */
- tb_list_entry_head_t coroutines_ready;
-
- // the suspend coroutines
- tb_list_entry_head_t coroutines_suspend;
-
-}tb_co_scheduler_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/* start the coroutine function
- *
- * @param scheduler the scheduler, uses the default scheduler if be null
- * @param func the coroutine function
- * @param priv the passed user private data as the argument of function
- * @param stacksize the stack size
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_co_scheduler_start(tb_co_scheduler_t* scheduler, tb_coroutine_func_t func, tb_cpointer_t priv, tb_size_t stacksize);
-
-/* yield the current coroutine
- *
- * @param scheduler the scheduler
- *
- * @return tb_true(yield ok) or tb_false(yield failed, no more coroutines)
- */
-tb_bool_t tb_co_scheduler_yield(tb_co_scheduler_t* scheduler);
-
-/*! resume the given coroutine (suspended)
- *
- * @param scheduler the scheduler
- * @param coroutine the suspended coroutine
- * @param priv the user private data as the return value of suspend() or sleep()
- *
- * @return the user private data from suspend(priv)
- */
-tb_pointer_t tb_co_scheduler_resume(tb_co_scheduler_t* scheduler, tb_coroutine_t* coroutine, tb_cpointer_t priv);
-
-/*! suspend the current coroutine
- *
- * @param scheduler the scheduler
- * @param priv the user private data as the return value of resume()
- *
- * @return the user private data from resume(priv)
- */
-tb_pointer_t tb_co_scheduler_suspend(tb_co_scheduler_t* scheduler, tb_cpointer_t priv);
-
-/* finish the current coroutine
- *
- * @param scheduler the scheduler
- */
-tb_void_t tb_co_scheduler_finish(tb_co_scheduler_t* scheduler);
-
-/* sleep the current coroutine
- *
- * @param scheduler the scheduler
- * @param interval the interval (ms), infinity: -1
- *
- * @return the user private data from resume(priv)
- */
-tb_pointer_t tb_co_scheduler_sleep(tb_co_scheduler_t* scheduler, tb_long_t interval);
-
-/* switch to the given coroutine
- *
- * @param scheduler the scheduler
- * @param coroutine the coroutine
- */
-tb_void_t tb_co_scheduler_switch(tb_co_scheduler_t* scheduler, tb_coroutine_t* coroutine);
-
-/*! wait io events
- *
- * @param scheduler the scheduler
- * @param sock the socket
- * @param events the waited events
- * @param timeout the timeout, infinity: -1
- *
- * @return > 0: the events, 0: timeout, -1: failed
- */
-tb_long_t tb_co_scheduler_wait(tb_co_scheduler_t* scheduler, tb_socket_ref_t sock, tb_size_t events, tb_long_t timeout);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/coroutine/impl/scheduler_io.c b/core/src/tbox/src/tbox/coroutine/impl/scheduler_io.c
deleted file mode 100644
index 35d6d178d..000000000
--- a/core/src/tbox/src/tbox/coroutine/impl/scheduler_io.c
+++ /dev/null
@@ -1,461 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file scheduler_io.c
- * @ingroup coroutine
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "scheduler_io"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "scheduler_io.h"
-#include "coroutine.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-// the ltimer grow
-#ifdef __tb_small__
-# define TB_SCHEDULER_IO_LTIMER_GROW (64)
-#else
-# define TB_SCHEDULER_IO_LTIMER_GROW (4096)
-#endif
-
-// the timer grow
-#define TB_SCHEDULER_IO_TIMER_GROW (TB_SCHEDULER_IO_LTIMER_GROW >> 4)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * private implementation
- */
-static tb_void_t tb_co_scheduler_io_resume(tb_co_scheduler_t* scheduler, tb_coroutine_t* coroutine, tb_cpointer_t priv)
-{
- // exists the timer task? remove it
- tb_cpointer_t task = coroutine->rs.wait.task;
- if (task)
- {
- // get io scheduler
- tb_co_scheduler_io_ref_t scheduler_io = tb_co_scheduler_io(scheduler);
- tb_assert(scheduler_io && scheduler_io->poller);
-
- // is high-precision timer?
- tb_size_t is_timer = (tb_size_t)(task) & 0x1;
-
- // check
- tb_assert((tb_size_t)task & (tb_size_t)~0x1);
-
- // remove the timer task
- if (__tb_unlikely__(is_timer)) tb_timer_task_exit(scheduler_io->timer, (tb_timer_task_ref_t)((tb_size_t)task & (tb_size_t)~0x1));
- else tb_ltimer_task_exit(scheduler_io->ltimer, (tb_ltimer_task_ref_t)task);
- coroutine->rs.wait.task = tb_null;
- }
-
- // clear waiting state
- coroutine->rs.wait.waiting = 0;
-
- // resume the coroutine
- tb_co_scheduler_resume(scheduler, coroutine, priv);
-}
-static tb_void_t tb_co_scheduler_io_timeout(tb_bool_t killed, tb_cpointer_t priv)
-{
- // check
- tb_coroutine_t* coroutine = (tb_coroutine_t*)priv;
- tb_assert(coroutine);
-
- // get scheduler
- tb_co_scheduler_t* scheduler = (tb_co_scheduler_t*)tb_coroutine_scheduler(coroutine);
- tb_assert(scheduler);
-
- // trace
- tb_trace_d("coroutine(%p): timer %s", coroutine, killed? "killed" : "timeout");
-
- // resume the coroutine
- tb_co_scheduler_io_resume(scheduler, coroutine, tb_null);
-}
-static tb_void_t tb_co_scheduler_io_events(tb_poller_ref_t poller, tb_socket_ref_t sock, tb_size_t events, tb_cpointer_t priv)
-{
- // check
- tb_coroutine_t* coroutine = (tb_coroutine_t*)priv;
- tb_assert(coroutine && poller && sock && priv);
-
- // get scheduler
- tb_co_scheduler_t* scheduler = (tb_co_scheduler_t*)tb_coroutine_scheduler(coroutine);
- tb_assert(scheduler);
-
- // trace
- tb_trace_d("coroutine(%p): socket: %p, events %lu", coroutine, sock, events);
-
- // waiting now?
- if (coroutine->rs.wait.waiting)
- {
- // eof for edge trigger?
- if (events & TB_POLLER_EVENT_EOF)
- {
- // cache this eof as next recv/send event
- events &= ~TB_POLLER_EVENT_EOF;
- coroutine->rs.wait.events_cache |= coroutine->rs.wait.events;
- }
-
- // resume the coroutine and pass the events to suspend()
- tb_co_scheduler_io_resume(scheduler, coroutine, (tb_cpointer_t)events);
- }
- // cache this events
- else coroutine->rs.wait.events_cache = events;
-}
-static tb_bool_t tb_co_scheduler_io_timer_spak(tb_co_scheduler_io_ref_t scheduler_io)
-{
- // check
- tb_assert(scheduler_io && scheduler_io->timer && scheduler_io->ltimer);
-
- // spak ctime
- tb_cache_time_spak();
-
- // spak timer
- if (!tb_timer_spak(scheduler_io->timer)) return tb_false;
-
- // spak ltimer
- if (!tb_ltimer_spak(scheduler_io->ltimer)) return tb_false;
-
- // pk
- return tb_true;
-}
-static tb_void_t tb_co_scheduler_io_loop(tb_cpointer_t priv)
-{
- // check
- tb_co_scheduler_io_ref_t scheduler_io = (tb_co_scheduler_io_ref_t)priv;
- tb_assert_and_check_return(scheduler_io && scheduler_io->timer && scheduler_io->ltimer);
-
- // the scheduler
- tb_co_scheduler_t* scheduler = scheduler_io->scheduler;
- tb_assert_and_check_return(scheduler);
-
- // the poller
- tb_poller_ref_t poller = scheduler_io->poller;
- tb_assert_and_check_return(poller);
-
- // loop
- while (!scheduler->stopped)
- {
- // finish all other ready coroutines first
- while (tb_co_scheduler_yield(scheduler))
- {
- // spak timer
- if (!tb_co_scheduler_io_timer_spak(scheduler_io)) break;
- }
-
- // no more suspended coroutines? loop end
- tb_check_break(tb_co_scheduler_suspend_count(scheduler));
-
- // the delay
- tb_size_t delay = tb_timer_delay(scheduler_io->timer);
-
- // the ldelay
- tb_size_t ldelay = tb_ltimer_delay(scheduler_io->ltimer);
-
- // trace
- tb_trace_d("loop: wait %lu ms ..", tb_min(delay, ldelay));
-
- // no more ready coroutines? wait io events and timers
- if (tb_poller_wait(poller, tb_co_scheduler_io_events, tb_min(delay, ldelay)) < 0) break;
-
- // spak timer
- if (!tb_co_scheduler_io_timer_spak(scheduler_io)) break;
- }
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_co_scheduler_io_ref_t tb_co_scheduler_io_init(tb_co_scheduler_t* scheduler)
-{
- // done
- tb_bool_t ok = tb_false;
- tb_co_scheduler_io_ref_t scheduler_io = tb_null;
- do
- {
- // init io scheduler
- scheduler_io = tb_malloc0_type(tb_co_scheduler_io_t);
- tb_assert_and_check_break(scheduler_io);
-
- // save scheduler
- scheduler_io->scheduler = (tb_co_scheduler_t*)scheduler;
-
- // init timer and using cache time
- scheduler_io->timer = tb_timer_init(TB_SCHEDULER_IO_TIMER_GROW, tb_true);
- tb_assert_and_check_break(scheduler_io->timer);
-
- // init ltimer and using cache time
- scheduler_io->ltimer = tb_ltimer_init(TB_SCHEDULER_IO_LTIMER_GROW, TB_LTIMER_TICK_S, tb_true);
- tb_assert_and_check_break(scheduler_io->ltimer);
-
- // init poller
- scheduler_io->poller = tb_poller_init(tb_null);
- tb_assert_and_check_break(scheduler_io->poller);
-
- // start the io loop coroutine
- if (!tb_co_scheduler_start(scheduler_io->scheduler, tb_co_scheduler_io_loop, scheduler_io, 0)) break;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit io scheduler
- if (scheduler_io) tb_co_scheduler_io_exit(scheduler_io);
- scheduler_io = tb_null;
- }
-
- // ok?
- return scheduler_io;
-}
-tb_void_t tb_co_scheduler_io_exit(tb_co_scheduler_io_ref_t scheduler_io)
-{
- // check
- tb_assert_and_check_return(scheduler_io);
-
- // exit poller
- if (scheduler_io->poller) tb_poller_exit(scheduler_io->poller);
- scheduler_io->poller = tb_null;
-
- // exit timer
- if (scheduler_io->timer) tb_timer_exit(scheduler_io->timer);
- scheduler_io->timer = tb_null;
-
- // exit ltimer
- if (scheduler_io->ltimer) tb_ltimer_exit(scheduler_io->ltimer);
- scheduler_io->ltimer = tb_null;
-
- // clear scheduler
- scheduler_io->scheduler = tb_null;
-
- // exit it
- tb_free(scheduler_io);
-}
-tb_void_t tb_co_scheduler_io_kill(tb_co_scheduler_io_ref_t scheduler_io)
-{
- // check
- tb_assert_and_check_return(scheduler_io);
-
- // trace
- tb_trace_d("kill: ..");
-
- // kill timer
- if (scheduler_io->timer) tb_timer_kill(scheduler_io->timer);
-
- // kill ltimer
- if (scheduler_io->ltimer) tb_ltimer_kill(scheduler_io->ltimer);
-
- // kill poller
- if (scheduler_io->poller) tb_poller_kill(scheduler_io->poller);
-}
-tb_pointer_t tb_co_scheduler_io_sleep(tb_co_scheduler_io_ref_t scheduler_io, tb_long_t interval)
-{
- // check
- tb_assert_and_check_return_val(scheduler_io && scheduler_io->poller && scheduler_io->scheduler, tb_null);
-
- // no sleep?
- tb_check_return_val(interval, tb_null);
-
- // get the current coroutine
- tb_coroutine_t* coroutine = tb_co_scheduler_running(scheduler_io->scheduler);
- tb_assert(coroutine);
-
- // trace
- tb_trace_d("coroutine(%p): sleep %ld ms ..", coroutine, interval);
-
- // infinity?
- if (interval > 0)
- {
- // high-precision interval?
- if (interval % 1000)
- {
- // post task to timer
- tb_timer_task_post(scheduler_io->timer, interval, tb_false, tb_co_scheduler_io_timeout, coroutine);
- }
- // low-precision interval?
- else
- {
- // post task to ltimer (faster)
- tb_ltimer_task_post(scheduler_io->ltimer, interval, tb_false, tb_co_scheduler_io_timeout, coroutine);
- }
- }
-
- // suspend it
- return tb_co_scheduler_suspend(scheduler_io->scheduler, tb_null);
-}
-tb_long_t tb_co_scheduler_io_wait(tb_co_scheduler_io_ref_t scheduler_io, tb_socket_ref_t sock, tb_size_t events, tb_long_t timeout)
-{
- // check
- tb_assert(scheduler_io && sock && scheduler_io->poller && scheduler_io->scheduler && events);
-
- // get the current coroutine
- tb_coroutine_t* coroutine = tb_co_scheduler_running(scheduler_io->scheduler);
- tb_assert(coroutine);
-
- // trace
- tb_trace_d("coroutine(%p): wait events(%lu) with %ld ms for socket(%p) ..", coroutine, events, timeout, sock);
-
- // enable edge-trigger mode if be supported
- if (tb_poller_support(scheduler_io->poller, TB_POLLER_EVENT_CLEAR))
- events |= TB_POLLER_EVENT_CLEAR;
-
- // exists this socket? only modify events
- tb_socket_ref_t sock_prev = coroutine->rs.wait.sock;
- if (sock_prev == sock)
- {
- // return the cached events directly if the waiting events exists cache
- tb_size_t events_prev = coroutine->rs.wait.events;
- tb_size_t events_cache = coroutine->rs.wait.events_cache;
- if (events_cache && (events_prev & events))
- {
- // clear cache events
- coroutine->rs.wait.events_cache &= ~events;
-
- // return the cached events
- return events_cache & events;
- }
-
- // modify socket from poller for waiting events if the waiting events has been changed
- if (events_prev != events && !tb_poller_modify(scheduler_io->poller, sock, events, coroutine))
- {
- // trace
- tb_trace_e("failed to modify sock(%p) to poller on coroutine(%p)!", sock, coroutine);
-
- // failed
- return -1;
- }
- }
- else
- {
- // remove the previous socket first if exists
- if (sock_prev && !tb_poller_remove(scheduler_io->poller, sock_prev))
- {
- // trace
- tb_trace_e("failed to remove sock(%p) to poller on coroutine(%p)!", sock_prev, coroutine);
-
- // failed
- return -1;
- }
-
- // insert socket to poller for waiting events
- if (!tb_poller_insert(scheduler_io->poller, sock, events, coroutine))
- {
- // trace
- tb_trace_e("failed to insert sock(%p) to poller on coroutine(%p)!", sock, coroutine);
-
- // failed
- return -1;
- }
- }
-
- // exists timeout?
- tb_cpointer_t task = tb_null;
- tb_bool_t is_ltimer = tb_false;
- if (timeout >= 0)
- {
- // high-precision interval?
- if (timeout % 1000)
- {
- // init task for timer
- task = tb_timer_task_init(scheduler_io->timer, timeout, tb_false, tb_co_scheduler_io_timeout, coroutine);
- tb_assert_and_check_return_val(task, tb_false);
- }
- // low-precision interval?
- else
- {
- // init task for ltimer (faster)
- task = tb_ltimer_task_init(scheduler_io->ltimer, timeout, tb_false, tb_co_scheduler_io_timeout, coroutine);
- tb_assert_and_check_return_val(task, tb_false);
-
- // mark as low-precision timer
- is_ltimer = tb_true;
- }
- }
-
- // check
- tb_assert(!((tb_size_t)(task) & 0x1));
-
- // save the timer task to coroutine
- coroutine->rs.wait.task = (is_ltimer || !task)? task : (tb_cpointer_t)((tb_size_t)(task) | 0x1);
-
- // save the socket to coroutine for the timer function
- coroutine->rs.wait.sock = sock;
-
- // save waiting events to coroutine
- coroutine->rs.wait.events = (tb_uint16_t)events;
- coroutine->rs.wait.events_cache = 0;
-
- // mark as waiting state
- coroutine->rs.wait.waiting = 1;
-
- // suspend the current coroutine and return the waited result
- return (tb_long_t)tb_co_scheduler_suspend(scheduler_io->scheduler, tb_null);
-}
-tb_bool_t tb_co_scheduler_io_cancel(tb_co_scheduler_io_ref_t scheduler_io, tb_socket_ref_t sock)
-{
- // check
- tb_assert(scheduler_io && sock && scheduler_io->poller && scheduler_io->scheduler);
-
- // get the current coroutine
- tb_coroutine_t* coroutine = tb_co_scheduler_running(scheduler_io->scheduler);
- tb_check_return_val(coroutine, tb_false);
-
- // trace
- tb_trace_d("coroutine(%p): cancel socket(%p) ..", coroutine, sock);
-
- // remove the this socket from poller
- if (coroutine->rs.wait.sock == sock)
- {
- // remove the previous socket first if exists
- if (!tb_poller_remove(scheduler_io->poller, sock))
- {
- // trace
- tb_trace_e("failed to remove sock(%p) to poller on coroutine(%p)!", sock, coroutine);
-
- // failed
- return tb_false;
- }
-
- // remove ok
- return tb_true;
- }
-
- // no this socket
- return tb_false;
-}
-tb_co_scheduler_io_ref_t tb_co_scheduler_io_self()
-{
- // get the current scheduler
- tb_co_scheduler_t* scheduler = (tb_co_scheduler_t*)tb_co_scheduler_self();
-
- // get the current io scheduler
- return scheduler? (tb_co_scheduler_io_ref_t)scheduler->scheduler_io : tb_null;
-}
diff --git a/core/src/tbox/src/tbox/coroutine/impl/scheduler_io.h b/core/src/tbox/src/tbox/coroutine/impl/scheduler_io.h
deleted file mode 100644
index 5afa01ab9..000000000
--- a/core/src/tbox/src/tbox/coroutine/impl/scheduler_io.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file scheduler_io.h
- * @ingroup coroutine
- *
- */
-#ifndef TB_COROUTINE_IMPL_SCHEDULER_IO_H
-#define TB_COROUTINE_IMPL_SCHEDULER_IO_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "scheduler.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the io scheduler type
-typedef struct __tb_co_scheduler_io_t
-{
- // is stopped?
- tb_bool_t stop;
-
- // the scheduler
- tb_co_scheduler_t* scheduler;
-
- // the poller
- tb_poller_ref_t poller;
-
- // the timer
- tb_timer_ref_t timer;
-
- // the low-precision timer (faster)
- tb_ltimer_ref_t ltimer;
-
-}tb_co_scheduler_io_t, *tb_co_scheduler_io_ref_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init io scheduler
- *
- * @return the io scheduler
- */
-tb_co_scheduler_io_ref_t tb_co_scheduler_io_init(tb_co_scheduler_t* scheduler);
-
-/*! exit io scheduler
- *
- * @param scheduler_io the io scheduler
- */
-tb_void_t tb_co_scheduler_io_exit(tb_co_scheduler_io_ref_t scheduler_io);
-
-/*! kill the current io scheduler
- *
- * @param scheduler_io the io scheduler
- */
-tb_void_t tb_co_scheduler_io_kill(tb_co_scheduler_io_ref_t scheduler_io);
-
-/* sleep the current coroutine
- *
- * @param scheduler_io the io scheduler
- * @param interval the interval (ms), infinity: -1
- *
- * @return the user private data from resume(priv)
- */
-tb_pointer_t tb_co_scheduler_io_sleep(tb_co_scheduler_io_ref_t scheduler_io, tb_long_t interval);
-
-/*! wait io events
- *
- * @param scheduler_io the io scheduler
- * @param sock the socket
- * @param events the waited events
- * @param timeout the timeout, infinity: -1
- *
- * @return > 0: the events, 0: timeout, -1: failed
- */
-tb_long_t tb_co_scheduler_io_wait(tb_co_scheduler_io_ref_t scheduler_io, tb_socket_ref_t sock, tb_size_t events, tb_long_t timeout);
-
-/*! cancel io events for the given socket
- *
- * @param scheduler_io the io scheduler
- * @param sock the socket
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_co_scheduler_io_cancel(tb_co_scheduler_io_ref_t scheduler_io, tb_socket_ref_t sock);
-
-/* get the current io scheduler
- *
- * @return the io scheduler
- */
-tb_co_scheduler_io_ref_t tb_co_scheduler_io_self(tb_noarg_t);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/coroutine/impl/stackless/coroutine.h b/core/src/tbox/src/tbox/coroutine/impl/stackless/coroutine.h
deleted file mode 100644
index 9571b12cc..000000000
--- a/core/src/tbox/src/tbox/coroutine/impl/stackless/coroutine.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file coroutine.h
- *
- */
-#ifndef TB_COROUTINE_IMPL_STACKLESS_COROUTINE_H
-#define TB_COROUTINE_IMPL_STACKLESS_COROUTINE_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the coroutine wait type
-typedef struct __tb_lo_coroutine_rs_wait_t
-{
-#ifndef TB_CONFIG_MICRO_ENABLE
- /* the timer task pointer for ltimer or timer
- *
- * for ltimer: task
- * for timer: task & 0x1
- */
- tb_cpointer_t task;
-#endif
-
- // the socket
- tb_socket_ref_t sock;
-
- // the waiting events
- tb_sint32_t events : 6;
-
- // the cached events
- tb_sint32_t events_cache : 6;
-
- // the events result (may be -1)
- tb_sint32_t events_result : 6;
-
- // is waiting?
- tb_sint32_t waiting : 1;
-
-}tb_lo_coroutine_rs_wait_t;
-
-/// the stackless coroutine type
-typedef struct __tb_lo_coroutine_t
-{
- // the coroutine core
- tb_lo_core_t core;
-
- // the list entry
- tb_list_entry_t entry;
-
- // the coroutine function
- tb_lo_coroutine_func_t func;
-
- // the user private data of the coroutine function
- tb_cpointer_t priv;
-
- // the user private data free function
- tb_lo_coroutine_free_t free;
-
- // the scheduler
- tb_lo_scheduler_ref_t scheduler;
-
- // the passed private data between resume() and suspend()
- union
- {
- // the arguments for wait()
- tb_lo_coroutine_rs_wait_t wait;
-
- } rs;
-
-}tb_lo_coroutine_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/* init coroutine
- *
- * @param scheduler the scheduler
- * @param func the coroutine function
- * @param priv the passed user private data as the argument of function
- * @param free the user private data free function
- *
- * @return the coroutine
- */
-tb_lo_coroutine_t* tb_lo_coroutine_init(tb_lo_scheduler_ref_t scheduler, tb_lo_coroutine_func_t func, tb_cpointer_t priv, tb_lo_coroutine_free_t free);
-
-/* reinit the given coroutine
- *
- * @param coroutine the coroutine
- * @param func the coroutine function
- * @param priv the passed user private data as the argument of function
- * @param free the user private data free function
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_lo_coroutine_reinit(tb_lo_coroutine_t* coroutine, tb_lo_coroutine_func_t func, tb_cpointer_t priv, tb_lo_coroutine_free_t free);
-
-/* exit coroutine
- *
- * @param coroutine the coroutine
- */
-tb_void_t tb_lo_coroutine_exit(tb_lo_coroutine_t* coroutine);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/coroutine/impl/stackless/prefix.h b/core/src/tbox/src/tbox/coroutine/impl/stackless/prefix.h
deleted file mode 100644
index 032c1f1a7..000000000
--- a/core/src/tbox/src/tbox/coroutine/impl/stackless/prefix.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file prefix.h
- *
- */
-#ifndef TB_COROUTINE_IMPL_STACKLESS_PREFIX_H
-#define TB_COROUTINE_IMPL_STACKLESS_PREFIX_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "../prefix.h"
-#include "../../stackless/coroutine.h"
-#include "../../../container/container.h"
-
-
-#endif
diff --git a/core/src/tbox/src/tbox/coroutine/impl/stackless/scheduler.h b/core/src/tbox/src/tbox/coroutine/impl/stackless/scheduler.h
deleted file mode 100644
index 44cf5a93f..000000000
--- a/core/src/tbox/src/tbox/coroutine/impl/stackless/scheduler.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file scheduler.h
- *
- */
-#ifndef TB_COROUTINE_IMPL_STACKLESS_SCHEDULER_H
-#define TB_COROUTINE_IMPL_STACKLESS_SCHEDULER_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "coroutine.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-// get the running coroutine
-#define tb_lo_scheduler_running(scheduler) ((scheduler)->running)
-
-// get the ready coroutines count
-#define tb_lo_scheduler_ready_count(scheduler) tb_list_entry_size(&(scheduler)->coroutines_ready)
-
-// get the suspended coroutines count
-#define tb_lo_scheduler_suspend_count(scheduler) tb_list_entry_size(&(scheduler)->coroutines_suspend)
-
-// get the io scheduler
-#define tb_lo_scheduler_io(scheduler) ((scheduler)->scheduler_io)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the io scheduler type
-struct __tb_lo_scheduler_io_t;
-
-/// the stackless coroutine scheduler type
-typedef struct __tb_lo_scheduler_t
-{
- // is stopped
- tb_bool_t stopped;
-
- // the running coroutine
- tb_lo_coroutine_t* running;
-
- // the io scheduler
- struct __tb_lo_scheduler_io_t* scheduler_io;
-
- // the dead coroutines
- tb_list_entry_head_t coroutines_dead;
-
- /* the ready coroutines
- *
- * ready: head -> ready -> .. -> running -> .. -> ready -> ..->
- * | |
- * ---------------------------<-----------------------
- */
- tb_list_entry_head_t coroutines_ready;
-
- // the suspend coroutines
- tb_list_entry_head_t coroutines_suspend;
-
-}tb_lo_scheduler_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/* start coroutine
- *
- * @param scheduler the scheduler
- * @param func the coroutine function
- * @param priv the passed user private data as the argument of function
- * @param free the user private data free function
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_lo_scheduler_start(tb_lo_scheduler_t* scheduler, tb_lo_coroutine_func_t func, tb_cpointer_t priv, tb_lo_coroutine_free_t free);
-
-/* resume the given coroutine
- *
- * @param scheduler the scheduler
- * @param coroutine the coroutine
- */
-tb_void_t tb_lo_scheduler_resume(tb_lo_scheduler_t* scheduler, tb_lo_coroutine_t* coroutine);
-
-/* get the current scheduler
- *
- * @return the scheduler
- */
-tb_lo_scheduler_ref_t tb_lo_scheduler_self_(tb_noarg_t);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/coroutine/impl/stackless/scheduler_io.c b/core/src/tbox/src/tbox/coroutine/impl/stackless/scheduler_io.c
deleted file mode 100644
index 5a1156a5c..000000000
--- a/core/src/tbox/src/tbox/coroutine/impl/stackless/scheduler_io.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file scheduler_io.c
- * @ingroup coroutine
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "scheduler_io"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "scheduler_io.h"
-#include "coroutine.h"
-#include "../../stackless/coroutine.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-// the ltimer grow
-#ifdef __tb_small__
-# define TB_SCHEDULER_IO_LTIMER_GROW (64)
-#else
-# define TB_SCHEDULER_IO_LTIMER_GROW (4096)
-#endif
-
-// the timer grow
-#define TB_SCHEDULER_IO_TIMER_GROW (TB_SCHEDULER_IO_LTIMER_GROW >> 4)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * private implementation
- */
-static tb_void_t tb_lo_scheduler_io_resume(tb_lo_scheduler_t* scheduler, tb_lo_coroutine_t* coroutine, tb_size_t events)
-{
- // clear waiting state
- coroutine->rs.wait.waiting = 0;
-
- // return events
- coroutine->rs.wait.events_result = (tb_sint32_t)events;
-
- // resume the coroutine
- tb_lo_scheduler_resume(scheduler, coroutine);
-}
-#ifndef TB_CONFIG_MICRO_ENABLE
-static tb_void_t tb_lo_scheduler_io_timeout(tb_bool_t killed, tb_cpointer_t priv)
-{
- // check
- tb_lo_coroutine_t* coroutine = (tb_lo_coroutine_t*)priv;
- tb_assert(coroutine);
-
- // get scheduler
- tb_lo_scheduler_t* scheduler = (tb_lo_scheduler_t*)coroutine->scheduler;
- tb_assert(scheduler);
-
- // trace
- tb_trace_d("coroutine(%p): timer %s", coroutine, killed? "killed" : "timeout");
-
- // resume the coroutine
- tb_lo_scheduler_io_resume(scheduler, coroutine, TB_POLLER_EVENT_NONE);
-}
-#endif
-static tb_void_t tb_lo_scheduler_io_events(tb_poller_ref_t poller, tb_socket_ref_t sock, tb_size_t events, tb_cpointer_t priv)
-{
- // check
- tb_lo_coroutine_t* coroutine = (tb_lo_coroutine_t*)priv;
- tb_assert(coroutine && poller && sock && priv);
-
- // get scheduler
- tb_lo_scheduler_t* scheduler = (tb_lo_scheduler_t*)coroutine->scheduler;
- tb_assert(scheduler);
-
- // trace
- tb_trace_d("coroutine(%p): socket: %p, events %lu", coroutine, sock, events);
-
- // waiting now?
- if (coroutine->rs.wait.waiting)
- {
- // eof for edge trigger?
- if (events & TB_POLLER_EVENT_EOF)
- {
- // cache this eof as next recv/send event
- events &= ~TB_POLLER_EVENT_EOF;
- coroutine->rs.wait.events_cache |= coroutine->rs.wait.events;
- }
-
- // resume the coroutine and pass the events to suspend()
- tb_lo_scheduler_io_resume(scheduler, coroutine, events);
- }
- // cache this events
- else coroutine->rs.wait.events_cache = events;
-}
-#ifndef TB_CONFIG_MICRO_ENABLE
-static tb_bool_t tb_lo_scheduler_io_timer_spak(tb_lo_scheduler_io_ref_t scheduler_io)
-{
- // check
- tb_assert(scheduler_io && scheduler_io->timer && scheduler_io->ltimer);
-
- // spak ctime
- tb_cache_time_spak();
-
- // spak timer
- if (!tb_timer_spak(scheduler_io->timer)) return tb_false;
-
- // spak ltimer
- if (!tb_ltimer_spak(scheduler_io->ltimer)) return tb_false;
-
- // pk
- return tb_true;
-}
-static tb_long_t tb_lo_scheduler_io_timer_delay(tb_lo_scheduler_io_ref_t scheduler_io)
-{
- // check
- tb_assert(scheduler_io && scheduler_io->timer && scheduler_io->ltimer);
-
- // the delay
- tb_size_t delay = tb_timer_delay(scheduler_io->timer);
-
- // the ldelay
- tb_size_t ldelay = tb_ltimer_delay(scheduler_io->ltimer);
-
- // return the timer delay
- return tb_min(delay, ldelay);
-}
-#else
-static __tb_inline__ tb_long_t tb_lo_scheduler_io_timer_delay(tb_lo_scheduler_io_ref_t scheduler_io)
-{
- return 1000;
-}
-#endif
-static tb_void_t tb_lo_scheduler_io_loop(tb_lo_coroutine_ref_t coroutine, tb_cpointer_t priv)
-{
- // check
- tb_lo_scheduler_io_ref_t scheduler_io = (tb_lo_scheduler_io_ref_t)priv;
- tb_assert(scheduler_io && scheduler_io->poller);
-
- // the scheduler
- tb_lo_scheduler_t* scheduler = scheduler_io->scheduler;
- tb_assert(scheduler);
-
- // enter coroutine
- tb_lo_coroutine_enter(coroutine)
- {
- // loop
- while (!scheduler->stopped)
- {
- // finish all other ready coroutines first
- while (tb_lo_scheduler_ready_count(scheduler) > 1)
- {
- // yield it
- tb_lo_coroutine_yield();
-
-#ifndef TB_CONFIG_MICRO_ENABLE
- // spak timer
- if (!tb_lo_scheduler_io_timer_spak(scheduler_io)) break;
-#endif
- }
-
- // no more suspended coroutines? loop end
- tb_check_break(tb_lo_scheduler_suspend_count(scheduler));
-
- // trace
- tb_trace_d("loop: wait %ld ms ..", tb_lo_scheduler_io_timer_delay(scheduler_io));
-
- // no more ready coroutines? wait io events and timers (TODO)
- if (tb_poller_wait(scheduler_io->poller, tb_lo_scheduler_io_events, tb_lo_scheduler_io_timer_delay(scheduler_io)) < 0) break;
-
-#ifndef TB_CONFIG_MICRO_ENABLE
- // spak timer
- if (!tb_lo_scheduler_io_timer_spak(scheduler_io)) break;
-#endif
- }
- }
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_lo_scheduler_io_ref_t tb_lo_scheduler_io_init(tb_lo_scheduler_t* scheduler)
-{
- // done
- tb_bool_t ok = tb_false;
- tb_lo_scheduler_io_ref_t scheduler_io = tb_null;
- do
- {
- // init io scheduler
- scheduler_io = tb_malloc0_type(tb_lo_scheduler_io_t);
- tb_assert_and_check_break(scheduler_io);
-
- // save scheduler
- scheduler_io->scheduler = (tb_lo_scheduler_t*)scheduler;
-
- // init poller
- scheduler_io->poller = tb_poller_init(tb_null);
- tb_assert_and_check_break(scheduler_io->poller);
-
-#ifndef TB_CONFIG_MICRO_ENABLE
- // init timer and using cache time
- scheduler_io->timer = tb_timer_init(TB_SCHEDULER_IO_TIMER_GROW, tb_true);
- tb_assert_and_check_break(scheduler_io->timer);
-
- // init ltimer and using cache time
- scheduler_io->ltimer = tb_ltimer_init(TB_SCHEDULER_IO_LTIMER_GROW, TB_LTIMER_TICK_S, tb_true);
- tb_assert_and_check_break(scheduler_io->ltimer);
-#endif
-
- // start the io loop coroutine
- if (!tb_lo_coroutine_start((tb_lo_scheduler_ref_t)scheduler, tb_lo_scheduler_io_loop, scheduler_io, tb_null)) break;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit io scheduler
- if (scheduler_io) tb_lo_scheduler_io_exit(scheduler_io);
- scheduler_io = tb_null;
- }
-
- // ok?
- return scheduler_io;
-}
-tb_void_t tb_lo_scheduler_io_exit(tb_lo_scheduler_io_ref_t scheduler_io)
-{
- // check
- tb_assert_and_check_return(scheduler_io);
-
- // exit poller
- if (scheduler_io->poller) tb_poller_exit(scheduler_io->poller);
- scheduler_io->poller = tb_null;
-
-#ifndef TB_CONFIG_MICRO_ENABLE
- // exit timer
- if (scheduler_io->timer) tb_timer_exit(scheduler_io->timer);
- scheduler_io->timer = tb_null;
-
- // exit ltimer
- if (scheduler_io->ltimer) tb_ltimer_exit(scheduler_io->ltimer);
- scheduler_io->ltimer = tb_null;
-#endif
-
- // clear scheduler
- scheduler_io->scheduler = tb_null;
-
- // exit it
- tb_free(scheduler_io);
-}
-tb_void_t tb_lo_scheduler_io_kill(tb_lo_scheduler_io_ref_t scheduler_io)
-{
- // check
- tb_assert_and_check_return(scheduler_io);
-
- // trace
- tb_trace_d("kill: ..");
-
-#ifndef TB_CONFIG_MICRO_ENABLE
- // kill timer
- if (scheduler_io->timer) tb_timer_kill(scheduler_io->timer);
-
- // kill ltimer
- if (scheduler_io->ltimer) tb_ltimer_kill(scheduler_io->ltimer);
-#endif
-
- // kill poller
- if (scheduler_io->poller) tb_poller_kill(scheduler_io->poller);
-}
-tb_void_t tb_lo_scheduler_io_sleep(tb_lo_scheduler_io_ref_t scheduler_io, tb_long_t interval)
-{
-#ifndef TB_CONFIG_MICRO_ENABLE
- // check
- tb_assert_and_check_return(scheduler_io && scheduler_io->poller && scheduler_io->scheduler);
-
- // get the current coroutine
- tb_lo_coroutine_t* coroutine = tb_lo_scheduler_running(scheduler_io->scheduler);
- tb_assert(coroutine);
-
- // trace
- tb_trace_d("coroutine(%p): sleep %ld ms ..", coroutine, interval);
-
- // infinity?
- if (interval > 0)
- {
- // high-precision interval?
- if (interval % 1000)
- {
- // post task to timer
- tb_timer_task_post(scheduler_io->timer, interval, tb_false, tb_lo_scheduler_io_timeout, coroutine);
- }
- // low-precision interval?
- else
- {
- // post task to ltimer (faster)
- tb_ltimer_task_post(scheduler_io->ltimer, interval, tb_false, tb_lo_scheduler_io_timeout, coroutine);
- }
- }
-#else
- // not impl
- tb_trace_noimpl();
-#endif
-}
-tb_bool_t tb_lo_scheduler_io_wait(tb_lo_scheduler_io_ref_t scheduler_io, tb_socket_ref_t sock, tb_size_t events, tb_long_t timeout)
-{
- // check
- tb_assert(scheduler_io && sock && scheduler_io->poller && scheduler_io->scheduler && events);
-
- // get the current coroutine
- tb_lo_coroutine_t* coroutine = tb_lo_scheduler_running(scheduler_io->scheduler);
- tb_assert(coroutine);
-
- // trace
- tb_trace_d("coroutine(%p): wait events(%lu) with %ld ms for socket(%p) ..", coroutine, events, timeout, sock);
-
- // enable edge-trigger mode if be supported
- if (tb_poller_support(scheduler_io->poller, TB_POLLER_EVENT_CLEAR))
- events |= TB_POLLER_EVENT_CLEAR;
-
- // exists this socket? only modify events
- tb_socket_ref_t sock_prev = coroutine->rs.wait.sock;
- if (sock_prev == sock)
- {
- // return the cached events directly if the waiting events exists cache
- tb_size_t events_prev = coroutine->rs.wait.events;
- tb_size_t events_cache = coroutine->rs.wait.events_cache;
- if (events_cache && (events_prev & events))
- {
- // clear cache events
- coroutine->rs.wait.events_cache &= ~events;
-
- // return the cached events
- coroutine->rs.wait.events_result = events_cache & events;
- return tb_false;
- }
-
- // modify socket from poller for waiting events if the waiting events has been changed
- if (events_prev != events && !tb_poller_modify(scheduler_io->poller, sock, events, coroutine))
- {
- // trace
- tb_trace_e("failed to modify sock(%p) to poller on coroutine(%p)!", sock, coroutine);
-
- // failed
- coroutine->rs.wait.events_result = -1;
- return tb_false;
- }
- }
- else
- {
- // remove the previous socket first if exists
- if (sock_prev && !tb_poller_remove(scheduler_io->poller, sock_prev))
- {
- // trace
- tb_trace_e("failed to remove sock(%p) to poller on coroutine(%p)!", sock_prev, coroutine);
-
- // failed
- coroutine->rs.wait.events_result = -1;
- return tb_false;
- }
-
- // insert socket to poller for waiting events
- if (!tb_poller_insert(scheduler_io->poller, sock, events, coroutine))
- {
- // trace
- tb_trace_e("failed to insert sock(%p) to poller on coroutine(%p)!", sock, coroutine);
-
- // failed
- coroutine->rs.wait.events_result = -1;
- return tb_false;
- }
- }
-
-#ifndef TB_CONFIG_MICRO_ENABLE
- // exists timeout?
- tb_cpointer_t task = tb_null;
- tb_bool_t is_ltimer = tb_false;
- if (timeout >= 0)
- {
- // high-precision interval?
- if (timeout % 1000)
- {
- // init task for timer
- task = tb_timer_task_init(scheduler_io->timer, timeout, tb_false, tb_lo_scheduler_io_timeout, coroutine);
- tb_assert_and_check_return_val(task, tb_false);
- }
- // low-precision interval?
- else
- {
- // init task for ltimer (faster)
- task = tb_ltimer_task_init(scheduler_io->ltimer, timeout, tb_false, tb_lo_scheduler_io_timeout, coroutine);
- tb_assert_and_check_return_val(task, tb_false);
-
- // mark as low-precision timer
- is_ltimer = tb_true;
- }
- }
-
- // check
- tb_assert(!((tb_size_t)(task) & 0x1));
-
- // save the timer task to coroutine
- coroutine->rs.wait.task = (is_ltimer || !task)? task : (tb_cpointer_t)((tb_size_t)(task) | 0x1);
-#endif
-
- // save the socket to coroutine for the timer function
- coroutine->rs.wait.sock = sock;
-
- // save waiting events to coroutine
- coroutine->rs.wait.events = (tb_sint32_t)events;
- coroutine->rs.wait.events_cache = 0;
- coroutine->rs.wait.events_result = 0;
-
- // mark as waiting state
- coroutine->rs.wait.waiting = 1;
-
- // suspend it
- return tb_true;
-}
-tb_bool_t tb_lo_scheduler_io_cancel(tb_lo_scheduler_io_ref_t scheduler_io, tb_socket_ref_t sock)
-{
- // check
- tb_assert(scheduler_io && sock && scheduler_io->poller && scheduler_io->scheduler);
-
- // get the current coroutine
- tb_lo_coroutine_t* coroutine = tb_lo_scheduler_running(scheduler_io->scheduler);
- tb_check_return_val(coroutine, tb_false);
-
- // trace
- tb_trace_d("coroutine(%p): cancel socket(%p) ..", coroutine, sock);
-
- // remove the this socket from poller
- if (coroutine->rs.wait.sock == sock)
- {
- // remove the previous socket first if exists
- if (!tb_poller_remove(scheduler_io->poller, sock))
- {
- // trace
- tb_trace_e("failed to remove sock(%p) to poller on coroutine(%p)!", sock, coroutine);
-
- // failed
- coroutine->rs.wait.events_result = -1;
- return tb_false;
- }
-
- // remove ok
- coroutine->rs.wait.events_result = 0;
- return tb_true;
- }
-
- // no this socket
- return tb_false;
-}
-tb_lo_scheduler_io_ref_t tb_lo_scheduler_io_self()
-{
- // get the current scheduler
- tb_lo_scheduler_t* scheduler = (tb_lo_scheduler_t*)tb_lo_scheduler_self_();
-
- // get the current io scheduler
- return scheduler? (tb_lo_scheduler_io_ref_t)scheduler->scheduler_io : tb_null;
-}
diff --git a/core/src/tbox/src/tbox/coroutine/impl/stackless/scheduler_io.h b/core/src/tbox/src/tbox/coroutine/impl/stackless/scheduler_io.h
deleted file mode 100644
index f73481260..000000000
--- a/core/src/tbox/src/tbox/coroutine/impl/stackless/scheduler_io.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file scheduler_io.h
- * @ingroup coroutine
- *
- */
-#ifndef TB_COROUTINE_IMPL_STACKLESS_SCHEDULER_IO_H
-#define TB_COROUTINE_IMPL_STACKLESS_SCHEDULER_IO_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "scheduler.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the io scheduler type
-typedef struct __tb_lo_scheduler_io_t
-{
- // is stopped?
- tb_bool_t stop;
-
- // the scheduler
- tb_lo_scheduler_t* scheduler;
-
- // the poller
- tb_poller_ref_t poller;
-
-#ifndef TB_CONFIG_MICRO_ENABLE
- // the timer
- tb_timer_ref_t timer;
-
- // the low-precision timer (faster)
- tb_ltimer_ref_t ltimer;
-#endif
-
-}tb_lo_scheduler_io_t, *tb_lo_scheduler_io_ref_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/* init io scheduler
- *
- * @return the io scheduler
- */
-tb_lo_scheduler_io_ref_t tb_lo_scheduler_io_init(tb_lo_scheduler_t* scheduler);
-
-/* exit io scheduler
- *
- * @param scheduler_io the io scheduler
- */
-tb_void_t tb_lo_scheduler_io_exit(tb_lo_scheduler_io_ref_t scheduler_io);
-
-/* kill the current io scheduler
- *
- * @param scheduler_io the io scheduler
- */
-tb_void_t tb_lo_scheduler_io_kill(tb_lo_scheduler_io_ref_t scheduler_io);
-
-/* sleep the current coroutine
- *
- * @param scheduler_io the io scheduler
- * @param interval the interval (ms), infinity: -1
- */
-tb_void_t tb_lo_scheduler_io_sleep(tb_lo_scheduler_io_ref_t scheduler_io, tb_long_t interval);
-
-/* wait io events
- *
- * @param scheduler_io the io scheduler
- * @param sock the socket
- * @param events the waited events
- * @param timeout the timeout, infinity: -1
- *
- * @return suspend coroutine if be tb_true
- */
-tb_bool_t tb_lo_scheduler_io_wait(tb_lo_scheduler_io_ref_t scheduler_io, tb_socket_ref_t sock, tb_size_t events, tb_long_t timeout);
-
-/*! cancel io events for the given socket
- *
- * @param scheduler_io the io scheduler
- * @param sock the socket
- *
- * return tb_true or tb_false
- */
-tb_bool_t tb_lo_scheduler_io_cancel(tb_lo_scheduler_io_ref_t scheduler_io, tb_socket_ref_t sock);
-
-/* get the current io scheduler
- *
- * @return the io scheduler
- */
-tb_lo_scheduler_io_ref_t tb_lo_scheduler_io_self(tb_noarg_t);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/coroutine/impl/stackless/stackless.h b/core/src/tbox/src/tbox/coroutine/impl/stackless/stackless.h
deleted file mode 100644
index 18dd9aa4d..000000000
--- a/core/src/tbox/src/tbox/coroutine/impl/stackless/stackless.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file coroutine.h
- *
- */
-#ifndef TB_COROUTINE_IMPL_STACKLESS_H
-#define TB_COROUTINE_IMPL_STACKLESS_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "coroutine.h"
-#include "scheduler.h"
-#include "scheduler_io.h"
-
-#endif
diff --git a/core/src/tbox/src/tbox/coroutine/lock.c b/core/src/tbox/src/tbox/coroutine/lock.c
deleted file mode 100644
index 9e40927d7..000000000
--- a/core/src/tbox/src/tbox/coroutine/lock.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file lock.h
- * @ingroup coroutine
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "lock"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "lock.h"
-#include "semaphore.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_co_lock_ref_t tb_co_lock_init()
-{
- // init lock
- return (tb_co_lock_ref_t)tb_co_semaphore_init(1);
-}
-tb_void_t tb_co_lock_exit(tb_co_lock_ref_t self)
-{
- // exit lock
- tb_co_semaphore_exit((tb_co_semaphore_ref_t)self);
-}
-tb_void_t tb_co_lock_enter(tb_co_lock_ref_t self)
-{
- // enter lock
- tb_co_semaphore_wait((tb_co_semaphore_ref_t)self, -1);
-}
-tb_bool_t tb_co_lock_enter_try(tb_co_lock_ref_t self)
-{
- // try to enter lock
- return tb_co_semaphore_wait((tb_co_semaphore_ref_t)self, 0) > 0;
-}
-tb_void_t tb_co_lock_leave(tb_co_lock_ref_t self)
-{
- // leave lock
- tb_co_semaphore_post((tb_co_semaphore_ref_t)self, 1);
-}
diff --git a/core/src/tbox/src/tbox/coroutine/lock.h b/core/src/tbox/src/tbox/coroutine/lock.h
deleted file mode 100644
index 1c3ab2473..000000000
--- a/core/src/tbox/src/tbox/coroutine/lock.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file lock.h
- * @ingroup coroutine
- *
- */
-#ifndef TB_COROUTINE_LOCK_H
-#define TB_COROUTINE_LOCK_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the coroutine lock ref type
-typedef __tb_typeref__(co_lock);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init lock
- *
- * @return the lock
- */
-tb_co_lock_ref_t tb_co_lock_init(tb_noarg_t);
-
-/*! exit lock
- *
- * @param lock the lock
- */
-tb_void_t tb_co_lock_exit(tb_co_lock_ref_t lock);
-
-/*! enter lock
- *
- * @param lock the lock
- */
-tb_void_t tb_co_lock_enter(tb_co_lock_ref_t lock);
-
-/*! try to enter lock
- *
- * @param lock the lock
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_co_lock_enter_try(tb_co_lock_ref_t lock);
-
-/*! leave lock
- *
- * @param lock the lock
- */
-tb_void_t tb_co_lock_leave(tb_co_lock_ref_t lock);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/coroutine/prefix.h b/core/src/tbox/src/tbox/coroutine/prefix.h
deleted file mode 100644
index a937c67c0..000000000
--- a/core/src/tbox/src/tbox/coroutine/prefix.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file prefix.h
- *
- */
-#ifndef TB_COROUTINE_PREFIX_H
-#define TB_COROUTINE_PREFIX_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "../prefix.h"
-
-
-#endif
diff --git a/core/src/tbox/src/tbox/coroutine/scheduler.c b/core/src/tbox/src/tbox/coroutine/scheduler.c
deleted file mode 100644
index bbe9016cd..000000000
--- a/core/src/tbox/src/tbox/coroutine/scheduler.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file scheduler.h
- * @ingroup scheduler
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "scheduler"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "scheduler.h"
-#include "impl/impl.h"
-#include "../algorithm/algorithm.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * globals
- */
-
-// the self scheduler local
-static tb_thread_local_t s_scheduler_self = TB_THREAD_LOCAL_INIT;
-
-// the global scheduler for the exclusive mode
-static tb_co_scheduler_t* s_scheduler_self_ex = tb_null;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * private implementation
- */
-static tb_void_t tb_co_scheduler_free(tb_list_entry_head_ref_t coroutines)
-{
- // check
- tb_assert(coroutines);
-
- // free all coroutines
- while (tb_list_entry_size(coroutines))
- {
- // get the next entry from head
- tb_list_entry_ref_t entry = tb_list_entry_head(coroutines);
- tb_assert(entry);
-
- // remove it from the ready coroutines
- tb_list_entry_remove_head(coroutines);
-
- // exit this coroutine
- tb_coroutine_exit((tb_coroutine_t*)tb_list_entry0(entry));
- }
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_co_scheduler_ref_t tb_co_scheduler_init()
-{
- // done
- tb_bool_t ok = tb_false;
- tb_co_scheduler_t* scheduler = tb_null;
- do
- {
- // make scheduler
- scheduler = tb_malloc0_type(tb_co_scheduler_t);
- tb_assert_and_check_break(scheduler);
-
- // init dead coroutines
- tb_list_entry_init(&scheduler->coroutines_dead, tb_coroutine_t, entry, tb_null);
-
- // init ready coroutines
- tb_list_entry_init(&scheduler->coroutines_ready, tb_coroutine_t, entry, tb_null);
-
- // init suspend coroutines
- tb_list_entry_init(&scheduler->coroutines_suspend, tb_coroutine_t, entry, tb_null);
-
- // init original coroutine
- scheduler->original.scheduler = (tb_co_scheduler_ref_t)scheduler;
-
- // init running
- scheduler->running = &scheduler->original;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (scheduler) tb_co_scheduler_exit((tb_co_scheduler_ref_t)scheduler);
- scheduler = tb_null;
- }
-
- // ok?
- return (tb_co_scheduler_ref_t)scheduler;
-}
-tb_void_t tb_co_scheduler_exit(tb_co_scheduler_ref_t self)
-{
- // check
- tb_co_scheduler_t* scheduler = (tb_co_scheduler_t*)self;
- tb_assert_and_check_return(scheduler);
-
- // must be stopped
- tb_assert(scheduler->stopped);
-
- // exit io scheduler first
- if (scheduler->scheduler_io) tb_co_scheduler_io_exit(scheduler->scheduler_io);
- scheduler->scheduler_io = tb_null;
-
- // clear running
- scheduler->running = tb_null;
-
- // check coroutines
- tb_assert(!tb_list_entry_size(&scheduler->coroutines_ready));
- tb_assert(!tb_list_entry_size(&scheduler->coroutines_suspend));
-
- // free all dead coroutines
- tb_co_scheduler_free(&scheduler->coroutines_dead);
-
- // free all ready coroutines
- tb_co_scheduler_free(&scheduler->coroutines_ready);
-
- // free all suspend coroutines
- tb_co_scheduler_free(&scheduler->coroutines_suspend);
-
- // exit dead coroutines
- tb_list_entry_exit(&scheduler->coroutines_dead);
-
- // exit ready coroutines
- tb_list_entry_exit(&scheduler->coroutines_ready);
-
- // exit suspend coroutines
- tb_list_entry_exit(&scheduler->coroutines_suspend);
-
- // exit the scheduler
- tb_free(scheduler);
-}
-tb_void_t tb_co_scheduler_kill(tb_co_scheduler_ref_t self)
-{
- // check
- tb_co_scheduler_t* scheduler = (tb_co_scheduler_t*)self;
- tb_assert_and_check_return(scheduler);
-
- // stop it
- scheduler->stopped = tb_true;
-
- // kill the io scheduler
- if (scheduler->scheduler_io) tb_co_scheduler_io_kill(scheduler->scheduler_io);
-}
-tb_void_t tb_co_scheduler_loop(tb_co_scheduler_ref_t self, tb_bool_t exclusive)
-{
- // check
- tb_co_scheduler_t* scheduler = (tb_co_scheduler_t*)self;
- tb_assert_and_check_return(scheduler);
-
- // is exclusive mode?
- if (exclusive) s_scheduler_self_ex = scheduler;
- else
- {
- // init self scheduler local
- if (!tb_thread_local_init(&s_scheduler_self, tb_null)) return ;
-
- // update and overide the current scheduler
- tb_thread_local_set(&s_scheduler_self, self);
- }
-
- // schedule all ready coroutines
- while (tb_list_entry_size(&scheduler->coroutines_ready))
- {
- // check
- tb_assert(tb_coroutine_is_original(scheduler->running));
-
- // get the next entry from head
- tb_list_entry_ref_t entry = tb_list_entry_head(&scheduler->coroutines_ready);
- tb_assert(entry);
-
- // switch to the next coroutine
- tb_co_scheduler_switch(scheduler, (tb_coroutine_t*)tb_list_entry0(entry));
-
- // trace
- tb_trace_d("[loop]: ready %lu", tb_list_entry_size(&scheduler->coroutines_ready));
- }
-
- // stop it
- scheduler->stopped = tb_true;
-
- // is exclusive mode?
- if (exclusive) s_scheduler_self_ex = tb_null;
- else
- {
- // clear the current scheduler
- tb_thread_local_set(&s_scheduler_self, tb_null);
- }
-}
-tb_co_scheduler_ref_t tb_co_scheduler_self()
-{
- // get self scheduler on the current thread
- return (tb_co_scheduler_ref_t)(s_scheduler_self_ex? s_scheduler_self_ex : tb_thread_local_get(&s_scheduler_self));
-}
diff --git a/core/src/tbox/src/tbox/coroutine/scheduler.h b/core/src/tbox/src/tbox/coroutine/scheduler.h
deleted file mode 100644
index 78ebdcb8c..000000000
--- a/core/src/tbox/src/tbox/coroutine/scheduler.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file scheduler.h
- * @ingroup coroutine
- *
- */
-#ifndef TB_COROUTINE_SCHEDULER_H
-#define TB_COROUTINE_SCHEDULER_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the coroutine scheduler ref type
-typedef __tb_typeref__(co_scheduler);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init scheduler
- *
- * @return the scheduler
- */
-tb_co_scheduler_ref_t tb_co_scheduler_init(tb_noarg_t);
-
-/*! exit scheduler
- *
- * @param scheduler the scheduler
- */
-tb_void_t tb_co_scheduler_exit(tb_co_scheduler_ref_t scheduler);
-
-/* kill the scheduler
- *
- * @param scheduler the scheduler
- */
-tb_void_t tb_co_scheduler_kill(tb_co_scheduler_ref_t scheduler);
-
-/*! run the scheduler loop
- *
- * @param scheduler the scheduler
- * @param exclusive enable exclusive mode, we need ensure only one loop() be called at the same time,
- * but it will be faster using thr global scheduler instead of TLS storage
- */
-tb_void_t tb_co_scheduler_loop(tb_co_scheduler_ref_t schedule, tb_bool_t exclusive);
-
-/*! get the scheduler of the current coroutine
- *
- * @return the scheduler
- */
-tb_co_scheduler_ref_t tb_co_scheduler_self(tb_noarg_t);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/coroutine/semaphore.c b/core/src/tbox/src/tbox/coroutine/semaphore.c
deleted file mode 100644
index be1335012..000000000
--- a/core/src/tbox/src/tbox/coroutine/semaphore.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file semaphore.h
- * @ingroup coroutine
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "semaphore"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "semaphore.h"
-#include "coroutine.h"
-#include "scheduler.h"
-#include "impl/impl.h"
-#include "../container/container.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the coroutine semaphore type
-typedef struct __tb_co_semaphore_t
-{
- // the semaphore value
- tb_size_t value;
-
- // the waiting coroutines
- tb_single_list_entry_head_t waiting;
-
-}tb_co_semaphore_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_co_semaphore_ref_t tb_co_semaphore_init(tb_size_t value)
-{
- // done
- tb_bool_t ok = tb_false;
- tb_co_semaphore_t* semaphore = tb_null;
- do
- {
- // make semaphore
- semaphore = tb_malloc0_type(tb_co_semaphore_t);
- tb_assert_and_check_break(semaphore);
-
- // init value
- semaphore->value = value;
-
- // init waiting coroutines
- tb_single_list_entry_init(&semaphore->waiting, tb_coroutine_t, rs.single_entry, tb_null);
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (semaphore) tb_co_semaphore_exit((tb_co_semaphore_ref_t)semaphore);
- semaphore = tb_null;
- }
-
- // ok?
- return (tb_co_semaphore_ref_t)semaphore;
-}
-tb_void_t tb_co_semaphore_exit(tb_co_semaphore_ref_t self)
-{
- // check
- tb_co_semaphore_t* semaphore = (tb_co_semaphore_t*)self;
- tb_assert_and_check_return(semaphore);
-
- // check waiting coroutines
- tb_assert(!tb_single_list_entry_size(&semaphore->waiting));
-
- // exit waiting coroutines
- tb_single_list_entry_exit(&semaphore->waiting);
-
- // exit the semaphore
- tb_free(semaphore);
-}
-tb_void_t tb_co_semaphore_post(tb_co_semaphore_ref_t self, tb_size_t post)
-{
- // check
- tb_co_semaphore_t* semaphore = (tb_co_semaphore_t*)self;
- tb_assert_and_check_return(semaphore);
-
- // add the semaphore value
- tb_size_t value = semaphore->value + post;
-
- // resume the waiting coroutines
- while (value && tb_single_list_entry_size(&semaphore->waiting))
- {
- // get the next entry from head
- tb_single_list_entry_ref_t entry = tb_single_list_entry_head(&semaphore->waiting);
- tb_assert_and_check_break(entry);
-
- // remove it from the waiting coroutines
- tb_single_list_entry_remove_head(&semaphore->waiting);
-
- // get the waiting coroutine
- tb_coroutine_ref_t coroutine = (tb_coroutine_ref_t)tb_single_list_entry(&semaphore->waiting, entry);
-
- // resume this coroutine
- tb_coroutine_resume(coroutine, (tb_cpointer_t)tb_true);
-
- // decrease the semaphore value
- value--;
- }
-
- // update the semaphore value
- semaphore->value = value;
-}
-tb_size_t tb_co_semaphore_value(tb_co_semaphore_ref_t self)
-{
- // check
- tb_co_semaphore_t* semaphore = (tb_co_semaphore_t*)self;
- tb_assert_and_check_return_val(semaphore, 0);
-
- // get the semaphore value
- return semaphore->value;
-}
-tb_long_t tb_co_semaphore_wait(tb_co_semaphore_ref_t self, tb_long_t timeout)
-{
- // check
- tb_co_semaphore_t* semaphore = (tb_co_semaphore_t*)self;
- tb_assert_and_check_return_val(semaphore, -1);
-
- // attempt to get the semaphore value
- tb_long_t ok = 1;
- if (semaphore->value) semaphore->value--;
- // no semaphore?
- else if (timeout)
- {
- // get the running coroutine
- tb_coroutine_t* running = (tb_coroutine_t*)tb_coroutine_self();
- tb_assert(running);
-
- // save this coroutine to the waiting coroutines
- tb_single_list_entry_insert_tail(&semaphore->waiting, &running->rs.single_entry);
-
- // wait semaphore
- ok = (tb_long_t)tb_coroutine_sleep(timeout);
- }
- // timeout and no waiting
- else ok = 0;
-
- // ok?
- return ok;
-}
diff --git a/core/src/tbox/src/tbox/coroutine/semaphore.h b/core/src/tbox/src/tbox/coroutine/semaphore.h
deleted file mode 100644
index a9eede0ac..000000000
--- a/core/src/tbox/src/tbox/coroutine/semaphore.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file semaphore.h
- * @ingroup coroutine
- *
- */
-#ifndef TB_COROUTINE_SEMAPHORE_H
-#define TB_COROUTINE_SEMAPHORE_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the coroutine semaphore ref type
-typedef __tb_typeref__(co_semaphore);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init semaphore
- *
- * @param value the initial semaphore value
- *
- * @return the semaphore
- */
-tb_co_semaphore_ref_t tb_co_semaphore_init(tb_size_t value);
-
-/*! exit semaphore
- *
- * @return the semaphore
- */
-tb_void_t tb_co_semaphore_exit(tb_co_semaphore_ref_t semaphore);
-
-/*! post semaphore
- *
- * @param semaphore the semaphore
- * @param post the post semaphore value
- *
- * @return tb_true or tb_false
- */
-tb_void_t tb_co_semaphore_post(tb_co_semaphore_ref_t semaphore, tb_size_t post);
-
-/*! the semaphore value
- *
- * @param semaphore the semaphore
- *
- * @return the semaphore value
- */
-tb_size_t tb_co_semaphore_value(tb_co_semaphore_ref_t semaphore);
-
-/*! wait semaphore
- *
- * @param semaphore the semaphore
- * @param timeout the timeout
- *
- * @return ok: 1, timeout: 0, fail: -1
- */
-tb_long_t tb_co_semaphore_wait(tb_co_semaphore_ref_t semaphore, tb_long_t timeout);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/coroutine/stackless/core.h b/core/src/tbox/src/tbox/coroutine/stackless/core.h
deleted file mode 100644
index 1322ed11a..000000000
--- a/core/src/tbox/src/tbox/coroutine/stackless/core.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file core.h
- * @ingroup coroutine
- *
- */
-#ifndef TB_COROUTINE_STACKLESS_CORE_H
-#define TB_COROUTINE_STACKLESS_CORE_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-/*
- * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
- * 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. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the Institute nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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.
- *
- */
-
-// get core from coroutine
-#define tb_lo_core(co) ((tb_lo_core_ref_t)(co))
-
-// get core state
-#define tb_lo_core_state(co) (tb_lo_core(co)->state)
-
-// set core state
-#define tb_lo_core_state_set(co, val) tb_lo_core(co)->state = (val)
-
-#ifdef TB_COMPILER_IS_GCC
-/*
- * Implementation of local continuations based on the "Labels as
- * values" feature of gcc
- *
- * @author Adam Dunkels <[email protected]>
- *
- * This implementation of local continuations is based on a special
- * feature of the GCC C compiler called "labels as values". This
- * feature allows assigning pointers with the address of the code
- * corresponding to a particular C label.
- *
- * For more information, see the GCC documentation:
- * http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
- */
-# define tb_lo_core_init(co) tb_lo_core(co)->branch = tb_null; tb_lo_core(co)->state = TB_STATE_READY
-# define tb_lo_core_resume(co) \
- if (tb_lo_core(co)->branch) \
- { \
- goto *(tb_lo_core(co)->branch); \
- } \
- else
-
-# define tb_lo_core_record(co) \
- do \
- { \
- __tb_mconcat_ex__(__tb_lo_core_label, __tb_line__): \
- tb_lo_core(co)->branch = &&__tb_mconcat_ex__(__tb_lo_core_label, __tb_line__); \
- \
- } while(0)
-
-# define tb_lo_core_exit(co) tb_lo_core(co)->branch = tb_null, tb_lo_core(co)->state = TB_STATE_END
-
-#else
-
-/*
- * Implementation of local continuations based on switch() statment
- *
- * @author Adam Dunkels <[email protected]>
- *
- * This implementation of local continuations uses the C switch()
- * statement to resume execution of a function somewhere inside the
- * function's body. The implementation is based on the fact that
- * switch() statements are able to jump directly into the bodies of
- * control structures such as if() or while() statmenets.
- *
- * This implementation borrows heavily from Simon Tatham's coroutines
- * implementation in C:
- * http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
- *
- *
- *
- * WARNING! the implementation using switch() does not work if an
- * core_set() is done within another switch() statement!
- */
-# define tb_lo_core_init(co) tb_lo_core(co)->branch = 0; tb_lo_core(co)->state = TB_STATE_READY
-# define tb_lo_core_resume(co) switch (tb_lo_core(co)->branch) case 0:
-# define tb_lo_core_record_(co, label) tb_lo_core(co)->branch = (tb_uint16_t)label; case label:
-# define tb_lo_core_exit(co) tb_lo_core(co)->branch = 0, tb_lo_core(co)->state = TB_STATE_END
-# ifdef TB_COMPILER_IS_MSVC
-# define tb_lo_core_record(co) tb_lo_core_record_(co, __COUNTER__ + 1)
-# else
-# define tb_lo_core_record(co) tb_lo_core_record_(co, __tb_line__)
-# endif
-#endif
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the core branch type
-#ifdef TB_COMPILER_IS_GCC
-typedef tb_pointer_t tb_lo_core_branch_t;
-#else
-typedef tb_uint16_t tb_lo_core_branch_t;
-#endif
-
-// the stackless coroutine core type
-typedef struct __tb_lo_core_t
-{
- // the code branch
- tb_lo_core_branch_t branch;
-
- /* the state
- *
- * TB_STATE_READY
- * TB_STATE_SUSPEND
- * TB_STATE_END
- */
- tb_uint8_t state;
-
-}tb_lo_core_t, *tb_lo_core_ref_t;
-
-
-#endif
diff --git a/core/src/tbox/src/tbox/coroutine/stackless/coroutine.c b/core/src/tbox/src/tbox/coroutine/stackless/coroutine.c
deleted file mode 100644
index c04769d2a..000000000
--- a/core/src/tbox/src/tbox/coroutine/stackless/coroutine.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file coroutine.h
- * @ingroup coroutine
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "coroutine"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "coroutine.h"
-#include "scheduler.h"
-#include "../impl/impl.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * private implementation
- */
-tb_lo_coroutine_t* tb_lo_coroutine_init(tb_lo_scheduler_ref_t scheduler, tb_lo_coroutine_func_t func, tb_cpointer_t priv, tb_lo_coroutine_free_t free)
-{
- // check
- tb_assert_and_check_return_val(scheduler && func, tb_null);
-
- // done
- tb_bool_t ok = tb_false;
- tb_lo_coroutine_t* coroutine = tb_null;
- do
- {
- // make coroutine
- coroutine = tb_malloc0_type(tb_lo_coroutine_t);
- tb_assert_and_check_break(coroutine);
-
- // init core
- tb_lo_core_init(&coroutine->core);
-
- // save scheduler
- coroutine->scheduler = scheduler;
-
- // init function and user private data
- coroutine->func = func;
- coroutine->priv = priv;
- coroutine->free = free;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (coroutine) tb_lo_coroutine_exit(coroutine);
- coroutine = tb_null;
- }
-
- // trace
- tb_trace_d("init %p", coroutine);
-
- // ok?
- return coroutine;
-}
-tb_bool_t tb_lo_coroutine_reinit(tb_lo_coroutine_t* coroutine, tb_lo_coroutine_func_t func, tb_cpointer_t priv, tb_lo_coroutine_free_t free)
-{
- // check
- tb_assert_and_check_return_val(coroutine && func, tb_false);
- tb_assert_and_check_return_val(coroutine->scheduler && tb_lo_core_state(coroutine) == TB_STATE_END, tb_false);
-
- // init core
- tb_lo_core_init(&coroutine->core);
-
- // init function and user private data
- coroutine->func = func;
- coroutine->priv = priv;
- coroutine->free = free;
-
- // init rs data
- tb_memset(&coroutine->rs, 0, sizeof(coroutine->rs));
-
- // ok
- return tb_true;
-}
-tb_void_t tb_lo_coroutine_exit(tb_lo_coroutine_t* coroutine)
-{
- // check
- tb_assert_and_check_return(coroutine && tb_lo_core_state(coroutine) == TB_STATE_END);
-
- // trace
- tb_trace_d("exit: %p", coroutine);
-
- // exit it
- tb_free(coroutine);
-}
-tb_lo_scheduler_ref_t tb_lo_coroutine_scheduler_(tb_lo_coroutine_ref_t self)
-{
- // check
- tb_lo_coroutine_t* coroutine = (tb_lo_coroutine_t*)self;
- tb_assert(coroutine);
-
- // get scheduler
- return coroutine->scheduler;
-}
-tb_void_t tb_lo_coroutine_sleep_(tb_lo_coroutine_ref_t self, tb_long_t interval)
-{
- // check
- tb_lo_coroutine_t* coroutine = (tb_lo_coroutine_t*)self;
- tb_assert(coroutine);
-
- // get scheduler
- tb_lo_scheduler_t* scheduler = (tb_lo_scheduler_t*)coroutine->scheduler;
- tb_assert(scheduler);
-
- // init io scheduler first
- if (!scheduler->scheduler_io) scheduler->scheduler_io = tb_lo_scheduler_io_init(scheduler);
- tb_assert(scheduler->scheduler_io);
-
- // sleep it
- tb_lo_scheduler_io_sleep(scheduler->scheduler_io, interval);
-}
-tb_bool_t tb_lo_coroutine_waitio_(tb_lo_coroutine_ref_t self, tb_socket_ref_t sock, tb_size_t events, tb_long_t timeout)
-{
- // check
- tb_lo_coroutine_t* coroutine = (tb_lo_coroutine_t*)self;
- tb_assert(coroutine);
-
- // get scheduler
- tb_lo_scheduler_t* scheduler = (tb_lo_scheduler_t*)coroutine->scheduler;
- tb_assert(scheduler);
-
- // init io scheduler first
- if (!scheduler->scheduler_io) scheduler->scheduler_io = tb_lo_scheduler_io_init(scheduler);
- tb_assert(scheduler->scheduler_io);
-
- // wait it
- return tb_lo_scheduler_io_wait(scheduler->scheduler_io, sock, events, timeout);
-}
-tb_long_t tb_lo_coroutine_events_(tb_lo_coroutine_ref_t self)
-{
- // check
- tb_lo_coroutine_t* coroutine = (tb_lo_coroutine_t*)self;
- tb_assert(coroutine);
-
- // get events
- return coroutine->rs.wait.events_result;
-}
-tb_void_t tb_lo_coroutine_pass_free_(tb_cpointer_t priv)
-{
- if (priv) tb_free(priv);
-}
-tb_pointer_t tb_lo_coroutine_pass1_make_(tb_size_t type_size, tb_cpointer_t value, tb_size_t offset, tb_size_t size)
-{
- // check
- tb_assert(type_size && value && offset + size <= type_size);
-
- // make data
- tb_byte_t* data = tb_malloc0_bytes(type_size);
- if (data) tb_memcpy(data + offset, value, size);
-
- // ok?
- return data;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * public implementation
- */
-tb_bool_t tb_lo_coroutine_start(tb_lo_scheduler_ref_t self, tb_lo_coroutine_func_t func, tb_cpointer_t priv, tb_lo_coroutine_free_t free)
-{
- return tb_lo_scheduler_start((tb_lo_scheduler_t*)self, func, priv, free);
-}
-tb_void_t tb_lo_coroutine_resume(tb_lo_coroutine_ref_t self)
-{
- tb_lo_scheduler_resume((tb_lo_scheduler_t*)tb_lo_coroutine_scheduler_(self), (tb_lo_coroutine_t*)self);
-}
diff --git a/core/src/tbox/src/tbox/coroutine/stackless/coroutine.h b/core/src/tbox/src/tbox/coroutine/stackless/coroutine.h
deleted file mode 100644
index cc71cb96d..000000000
--- a/core/src/tbox/src/tbox/coroutine/stackless/coroutine.h
+++ /dev/null
@@ -1,413 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file coroutine.h
- * @ingroup coroutine
- *
- */
-#ifndef TB_COROUTINE_STACKLESS_COROUTINE_H
-#define TB_COROUTINE_STACKLESS_COROUTINE_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "core.h"
-#include "scheduler.h"
-#include "../../libc/libc.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-/// the self coroutine
-#define tb_lo_coroutine_self() (co__)
-
-/* enter coroutine
- *
- * @code
- *
- // before
- tb_lo_coroutine_enter(co)
- {
- for (i = 0; i < 100; i++)
- {
- tb_lo_coroutine_yield();
- }
- }
-
- // after expanding again (init: branch = 0, state = TB_STATE_READY)
- tb_lo_coroutine_ref_t co__ = co;
- tb_int_t lo_yield_flag__ = 1;
- for (; lo_yield_flag__; tb_lo_core(co__)->branch = 0, tb_lo_core(co__)->state = TB_STATE_END, lo_yield_flag__ = 0)
- switch (tb_lo_core(co__)->branch)
- case 0:
- {
- for (i = 0; i < 100; i++)
- {
- lo_yield_flag__ = 0;
- tb_lo_core(co__)->branch = __tb_line__; case __tb_line__:;
- if (lo_yield_flag__ == 0)
- return ;
- }
- }
-
- // or ..
-
- // after expanding again for gcc label (init: branch = tb_null, state = TB_STATE_READY)
- tb_lo_coroutine_ref_t co__ = co;
- tb_int_t lo_yield_flag__ = 1;
- for (; lo_yield_flag__; tb_lo_core(co__)->branch = tb_null, tb_lo_core(co__)->state = TB_STATE_END, lo_yield_flag__ = 0)
- if (tb_lo_core(co)->branch)
- {
- goto *(tb_lo_core(co)->branch);
- }
- else
- {
- for (i = 0; i < 100; i++)
- {
- lo_yield_flag__ = 0;
- do
- {
- __tb_mconcat_ex__(__tb_lo_core_label, __tb_line__):
- tb_lo_core(co)->branch = &&__tb_mconcat_ex__(__tb_lo_core_label, __tb_line__);
-
- } while(0)
-
- if (lo_yield_flag__ == 0)
- return ;
- }
- }
-
- * @endcode
- */
-#define tb_lo_coroutine_enter(co) \
- tb_lo_coroutine_ref_t co__ = (co); \
- tb_int_t lo_yield_flag__ = 1; \
- for ( ; lo_yield_flag__; tb_lo_core_exit(tb_lo_coroutine_self()), lo_yield_flag__ = 0) \
- tb_lo_core_resume(tb_lo_coroutine_self())
-
-/// yield coroutine
-#define tb_lo_coroutine_yield() \
-do \
-{ \
- lo_yield_flag__ = 0; \
- tb_lo_core_record(co__); \
- if (lo_yield_flag__ == 0) \
- return ; \
- \
-} while(0)
-
-/*! suspend current coroutine
- *
- * the scheduler will move this coroutine to the suspended coroutines after the function be returned
- *
- * @code
- *
- // before
- tb_lo_coroutine_enter(co)
- {
- for (i = 0; i < 100; i++)
- {
- tb_lo_coroutine_yield();
- tb_lo_coroutine_suspend();
- }
- }
-
- // after expanding again (init: branch = 0, state = TB_STATE_READY)
- tb_lo_coroutine_ref_t co__ = co;
- tb_int_t lo_yield_flag__ = 1;
- for (; lo_yield_flag__; tb_lo_core(co__)->branch = 0, tb_lo_core(co__)->state = TB_STATE_END, lo_yield_flag__ = 0)
- switch (tb_lo_core(co__)->branch)
- case 0:
- {
- for (i = 0; i < 100; i++)
- {
- lo_yield_flag__ = 0;
- tb_lo_core(co__)->branch = __tb_line__; case __tb_line__:;
- if (lo_yield_flag__ == 0)
- return ;
-
- // suspend coroutine
- tb_lo_core(co__)->state = TB_STATE_SUSPEND;
- tb_lo_core(co__)->branch = __tb_line__; case __tb_line__:;
- if (tb_lo_core(co__)->state == TB_STATE_SUSPEND)
- return ;
- }
- }
- * @endcode
- */
-#define tb_lo_coroutine_suspend() \
-do \
-{ \
- tb_used(&lo_yield_flag__); \
- tb_lo_core_state_set(tb_lo_coroutine_self(), TB_STATE_SUSPEND); \
- tb_lo_core_record(tb_lo_coroutine_self()); \
- if (tb_lo_core_state(tb_lo_coroutine_self()) == TB_STATE_SUSPEND) \
- return ; \
- \
-} while(0)
-
-/// sleep some time
-#define tb_lo_coroutine_sleep(interval) \
-do \
-{ \
- if (interval) \
- { \
- tb_lo_coroutine_sleep_(tb_lo_coroutine_self(), interval); \
- tb_lo_coroutine_suspend(); \
- } \
- \
-} while(0)
-
-/// wait io socket events
-#define tb_lo_coroutine_waitio(sock, events, interval) \
-do \
-{ \
- if (tb_lo_coroutine_waitio_(tb_lo_coroutine_self(), sock, events, interval)) \
- { \
- tb_lo_coroutine_suspend(); \
- } \
- \
-} while(0)
-
-/// wait until coroutine be true
-#define tb_lo_coroutine_wait_until(cond) \
-do \
-{ \
- tb_used(&lo_yield_flag__); \
- tb_lo_core_record(tb_lo_coroutine_self()); \
- if (!(cond)) \
- return ; \
- \
-} while(0)
-
-/// wait while coroutine be true
-#define tb_lo_coroutine_wait_while(pt, cond) tb_lo_coroutine_wait_until(!(cond))
-
-/// get socket events after waiting
-#define tb_lo_coroutine_events() tb_lo_coroutine_events_(tb_lo_coroutine_self())
-
-/*! pass the user private data
- *
- * @code
-
- // start coroutine
- tb_lo_coroutine_start(scheduler, coroutine_func, tb_lo_coroutine_pass(tb_xxxx_priv_t));
-
- * @endcode
- *
- * =>
- *
- * @code
-
- // start coroutine
- tb_lo_coroutine_start(scheduler, coroutine_func, tb_malloc0_type(tb_xxxx_priv_t), tb_lo_coroutine_pass_free_);
-
- * @endcode
- */
-#define tb_lo_coroutine_pass(type) tb_malloc0_type(type), tb_lo_coroutine_pass_free_
-
-/*! pass the user private data and init one member
- *
- * @code
-
- typedef struct __tb_xxxx_priv_t
- {
- tb_size_t member;
- tb_size_t others;
-
- }tb_xxxx_priv_t;
-
- // start coroutine
- tb_lo_coroutine_start(scheduler, coroutine_func, tb_lo_coroutine_pass1(tb_xxxx_priv_t, member, value));
-
- * @endcode
- *
- * =>
- *
- * @code
-
- tb_xxxx_priv_t* priv = tb_malloc0_type(tb_xxxx_priv_t);
- if (priv)
- {
- priv->member = value;
- }
-
- // start coroutine
- tb_lo_coroutine_start(scheduler, coroutine_func, priv, tb_lo_coroutine_pass_free_);
-
- * @endcode
- */
-#define tb_lo_coroutine_pass1(type, member, value) tb_lo_coroutine_pass1_make_(sizeof(type), &(value), tb_offsetof(type, member), tb_memsizeof(type, member)), tb_lo_coroutine_pass_free_
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * private interfaces
- */
-
-/* get the scheduler of coroutine
- *
- * @param coroutine the coroutine
- *
- * @return the scheduler
- */
-tb_lo_scheduler_ref_t tb_lo_coroutine_scheduler_(tb_lo_coroutine_ref_t coroutine);
-
-/* sleep the current coroutine
- *
- * @param coroutine the coroutine
- * @param interval the interval (ms), infinity: -1
- */
-tb_void_t tb_lo_coroutine_sleep_(tb_lo_coroutine_ref_t coroutine, tb_long_t interval);
-
-/* wait io events
- *
- * @param coroutine the coroutine
- * @param sock the socket
- * @param events the waited events
- * @param timeout the timeout, infinity: -1
- *
- * @return suspend coroutine if be tb_true
- */
-tb_bool_t tb_lo_coroutine_waitio_(tb_lo_coroutine_ref_t coroutine, tb_socket_ref_t sock, tb_size_t events, tb_long_t timeout);
-
-/* get the events after waiting socket
- *
- * @param coroutine the coroutine
- *
- * @return events: > 0, failed: -1, timeout: 0
- */
-tb_long_t tb_lo_coroutine_events_(tb_lo_coroutine_ref_t coroutine);
-
-/* free the user private data for pass()
- *
- * @note only be a wrapper of free() for tb_lo_coroutine_pass()
- *
- * @param priv the user private data
- */
-tb_void_t tb_lo_coroutine_pass_free_(tb_cpointer_t priv);
-
-/* make the user private data for pass1()
- *
- * @param type_size the data type size
- * @param value the value pointer
- * @param offset the member offset
- * @param size the value size
- *
- * @return the user private data
- */
-tb_pointer_t tb_lo_coroutine_pass1_make_(tb_size_t type_size, tb_cpointer_t value, tb_size_t offset, tb_size_t size);
-
-/* make the user private data for pass2()
- *
- * @param type_size the data type size
- * @param value1 the value1 pointer
- * @param offset1 the member1 offset
- * @param size1 the value1 size
- * @param value2 the value2 pointer
- * @param offset2 the member2 offset
- * @param size2 the value2 size
- *
- * @return the user private data
- */
-tb_pointer_t tb_lo_coroutine_pass2_make_(tb_size_t type_size, tb_cpointer_t value1, tb_size_t offset1, tb_size_t size1, tb_cpointer_t value2, tb_size_t offset2, tb_size_t size2);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! start coroutine
- *
- * @code
- static tb_void_t switchtask(tb_lo_coroutine_ref_t coroutine, tb_cpointer_t priv)
- {
- // get count pointer (@note only allow non-status local variables)
- tb_size_t* count = (tb_size_t*)priv;
-
- // enter coroutine
- tb_lo_coroutine_enter(coroutine);
-
- // @note can not define local variables here
- // ...
-
- // loop
- while ((*count)--)
- {
- // yield
- tb_lo_coroutine_yield();
- }
-
- // leave coroutine
- tb_lo_coroutine_leave();
- }
-
- tb_int_t main (tb_int_t argc, tb_char_t** argv)
- {
- // init tbox
- if (!tb_init(tb_null, tb_null)) return -1;
-
- // init scheduler
- tb_lo_scheduler_ref_t scheduler = tb_lo_scheduler_init();
- if (scheduler)
- {
- // start coroutine
- tb_size_t counts[] = {100, 100};
- tb_lo_coroutine_start(scheduler, switchtask, &counts[0], tb_null);
- tb_lo_coroutine_start(scheduler, switchtask, &counts[1], tb_null);
-
- // run scheduler
- tb_lo_scheduler_loop(scheduler);
-
- // exit scheduler
- tb_lo_scheduler_exit(scheduler);
- }
-
- // exit tbox
- tb_exit();
- }
-
- * @endcode
- *
- * @param scheduler the scheduler (can not be null, we can get scheduler of the current coroutine from tb_lo_scheduler_self())
- * @param func the coroutine function
- * @param priv the passed user private data as the argument of function
- * @param free the user private free function
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_lo_coroutine_start(tb_lo_scheduler_ref_t scheduler, tb_lo_coroutine_func_t func, tb_cpointer_t priv, tb_lo_coroutine_free_t free);
-
-/*! resume the given coroutine
- *
- * @param coroutine the coroutine
- */
-tb_void_t tb_lo_coroutine_resume(tb_lo_coroutine_ref_t coroutine);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/coroutine/stackless/lock.h b/core/src/tbox/src/tbox/coroutine/stackless/lock.h
deleted file mode 100644
index a5b82f3f7..000000000
--- a/core/src/tbox/src/tbox/coroutine/stackless/lock.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file lock.h
- * @ingroup coroutine
- *
- */
-#ifndef TB_COROUTINE_STACKLESS_LOCK_H
-#define TB_COROUTINE_STACKLESS_LOCK_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "semaphore.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-/*! init lock
- *
- * @param lock the lock pointer
- */
-#define tb_lo_lock_init(lock) tb_lo_semaphore_init(lock, 1)
-
-/*! exit lock
- *
- * @param lock the lock pointer
- */
-#define tb_lo_lock_exit(lock) tb_lo_semaphore_exit(lock)
-
-/*! enter lock
- *
- * @param lock the lock pointer
- */
-#define tb_lo_lock_enter(lock) tb_lo_semaphore_wait(lock)
-
-/*! try to enter lock
- *
- * @param lock the lock pointer
- *
- * @return tb_true or tb_false
- */
-#define tb_lo_lock_enter_try(lock) tb_lo_semaphore_wait_try(lock)
-
-/*! leave lock
- *
- * @param lock the lock pointer
- */
-#define tb_lo_lock_leave(lock) tb_lo_semaphore_post(lock, 1)
-
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the stackless lock type
-typedef tb_lo_semaphore_t tb_lo_lock_t;
-
-/// the stackless lock ref type
-typedef tb_lo_semaphore_ref_t tb_lo_lock_ref_t;
-
-#endif
diff --git a/core/src/tbox/src/tbox/coroutine/stackless/prefix.h b/core/src/tbox/src/tbox/coroutine/stackless/prefix.h
deleted file mode 100644
index 1abfd678f..000000000
--- a/core/src/tbox/src/tbox/coroutine/stackless/prefix.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file prefix.h
- *
- */
-#ifndef TB_COROUTINE_STACKLESS_PREFIX_H
-#define TB_COROUTINE_STACKLESS_PREFIX_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "../prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the stackless coroutine ref type
-typedef __tb_typeref__(lo_coroutine);
-
-/// the stackless scheduler ref type
-typedef __tb_typeref__(lo_scheduler);
-
-/*! the coroutine function type
- *
- * @param coroutine the coroutine self
- * @param priv the user private data from start(.., priv)
- */
-typedef tb_void_t (*tb_lo_coroutine_func_t)(tb_lo_coroutine_ref_t coroutine, tb_cpointer_t priv);
-
-/*! the user private data free function type
- *
- * @param priv the user private data from start(.., priv)
- */
-typedef tb_void_t (*tb_lo_coroutine_free_t)(tb_cpointer_t priv);
-
-
-#endif
diff --git a/core/src/tbox/src/tbox/coroutine/stackless/scheduler.c b/core/src/tbox/src/tbox/coroutine/stackless/scheduler.c
deleted file mode 100644
index 3f996e7f2..000000000
--- a/core/src/tbox/src/tbox/coroutine/stackless/scheduler.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file scheduler.h
- * @ingroup scheduler
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "scheduler"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "scheduler.h"
-#include "../impl/impl.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-// the dead cache maximum count
-#if defined(TB_CONFIG_MICRO_ENABLE)
-# define TB_SCHEDULER_DEAD_CACHE_MAXN (8)
-#elif defined(__tb_small__)
-# define TB_SCHEDULER_DEAD_CACHE_MAXN (64)
-#else
-# define TB_SCHEDULER_DEAD_CACHE_MAXN (256)
-#endif
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * globals
- */
-
-#ifndef TB_CONFIG_MICRO_ENABLE
-// the self scheduler local
-static tb_thread_local_t s_scheduler_self = TB_THREAD_LOCAL_INIT;
-#endif
-
-// the global scheduler for the exclusive mode
-static tb_lo_scheduler_t* s_scheduler_self_ex = tb_null;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * private implementation
- */
-static tb_void_t tb_lo_scheduler_free(tb_list_entry_head_ref_t coroutines)
-{
- // check
- tb_assert(coroutines);
-
- // free all coroutines
- while (tb_list_entry_size(coroutines))
- {
- // get the next entry from head
- tb_list_entry_ref_t entry = tb_list_entry_head(coroutines);
- tb_assert(entry);
-
- // remove it from the ready coroutines
- tb_list_entry_remove_head(coroutines);
-
- // exit this coroutine
- tb_lo_coroutine_exit((tb_lo_coroutine_t*)tb_list_entry(coroutines, entry));
- }
-}
-static tb_void_t tb_lo_scheduler_make_ready(tb_lo_scheduler_t* scheduler, tb_lo_coroutine_t* coroutine)
-{
- // check
- tb_assert(scheduler && coroutine);
-
- // mark ready state
- tb_lo_core_state_set(coroutine, TB_STATE_READY);
-
- // insert this coroutine to ready coroutines
- if (scheduler->running)
- {
- // .. -> coroutine(inserted) -> running -> ..
- tb_list_entry_insert_prev(&scheduler->coroutines_ready, &scheduler->running->entry, &coroutine->entry);
- }
- else
- {
- // .. last -> coroutine(inserted)
- tb_list_entry_insert_tail(&scheduler->coroutines_ready, &coroutine->entry);
- }
-}
-static tb_void_t tb_lo_scheduler_make_dead(tb_lo_scheduler_t* scheduler, tb_lo_coroutine_t* coroutine)
-{
- // check
- tb_assert(scheduler && coroutine);
- tb_assert(tb_lo_core_state(coroutine) == TB_STATE_END);
-
- // trace
- tb_trace_d("finish coroutine(%p)", coroutine);
-
- // free the user private data first
- if (coroutine->free) coroutine->free(coroutine->priv);
-
- // remove this coroutine from the ready coroutines
- tb_list_entry_remove(&scheduler->coroutines_ready, &coroutine->entry);
-
- // append this coroutine to dead coroutines
- tb_list_entry_insert_tail(&scheduler->coroutines_dead, &coroutine->entry);
-}
-static tb_void_t tb_lo_scheduler_make_suspend(tb_lo_scheduler_t* scheduler, tb_lo_coroutine_t* coroutine)
-{
- // check
- tb_assert(scheduler && coroutine);
- tb_assert(tb_lo_core_state(coroutine) == TB_STATE_SUSPEND);
-
- // trace
- tb_trace_d("suspend coroutine(%p)", coroutine);
-
- // remove this coroutine from the ready coroutines
- tb_list_entry_remove(&scheduler->coroutines_ready, &coroutine->entry);
-
- // append this coroutine to suspend coroutines
- tb_list_entry_insert_tail(&scheduler->coroutines_suspend, &coroutine->entry);
-}
-static __tb_inline__ tb_lo_coroutine_t* tb_lo_scheduler_next_ready(tb_lo_scheduler_t* scheduler)
-{
- // check
- tb_assert(scheduler && tb_list_entry_size(&scheduler->coroutines_ready));
-
- // get the next entry
- tb_list_entry_ref_t entry_next = scheduler->running? tb_list_entry_next(&scheduler->running->entry) : tb_list_entry_head(&scheduler->coroutines_ready);
- tb_assert(entry_next);
-
- // is list header? skip it and get the first entry
- if (entry_next == (tb_list_entry_ref_t)&scheduler->coroutines_ready)
- entry_next = tb_list_entry_next(entry_next);
-
- // get the next ready coroutine
- return (tb_lo_coroutine_t*)tb_list_entry(&scheduler->coroutines_ready, entry_next);
-}
-static tb_void_t tb_lo_scheduler_switch(tb_lo_scheduler_t* scheduler, tb_lo_coroutine_t* coroutine)
-{
- // check
- tb_assert(scheduler && coroutine && coroutine->func);
- tb_assert(tb_lo_core_state(coroutine) == TB_STATE_READY);
-
- // trace
- tb_trace_d("switch to coroutine(%p) from coroutine(%p)", coroutine, scheduler->running);
-
- // mark the given coroutine as running
- scheduler->running = coroutine;
-
- // call the coroutine function
- coroutine->func((tb_lo_coroutine_ref_t)coroutine, coroutine->priv);
-}
-tb_bool_t tb_lo_scheduler_start(tb_lo_scheduler_t* scheduler, tb_lo_coroutine_func_t func, tb_cpointer_t priv, tb_lo_coroutine_free_t free)
-{
- // check
- tb_assert(func);
-
- // done
- tb_bool_t ok = tb_false;
- tb_lo_coroutine_t* coroutine = tb_null;
- do
- {
- // trace
- tb_trace_d("start ..");
-
- // get the current scheduler
- if (!scheduler) scheduler = (tb_lo_scheduler_t*)tb_lo_scheduler_self_();
- tb_assert_and_check_break(scheduler);
-
- // have been stopped? do not continue to start new coroutines
- tb_check_break(!scheduler->stopped);
-
- // reuses dead coroutines in init function
- if (tb_list_entry_size(&scheduler->coroutines_dead))
- {
- // get the next entry from head
- tb_list_entry_ref_t entry = tb_list_entry_head(&scheduler->coroutines_dead);
- tb_assert_and_check_break(entry);
-
- // remove it from the ready coroutines
- tb_list_entry_remove_head(&scheduler->coroutines_dead);
-
- // get the dead coroutine
- coroutine = (tb_lo_coroutine_t*)tb_list_entry(&scheduler->coroutines_dead, entry);
-
- // reinit this coroutine
- tb_lo_coroutine_reinit(coroutine, func, priv, free);
- }
-
- // init coroutine
- if (!coroutine) coroutine = tb_lo_coroutine_init((tb_lo_scheduler_ref_t)scheduler, func, priv, free);
- tb_assert_and_check_break(coroutine);
-
- // ready coroutine
- tb_lo_scheduler_make_ready(scheduler, coroutine);
-
- // the dead coroutines is too much? free some coroutines
- while (tb_list_entry_size(&scheduler->coroutines_dead) > TB_SCHEDULER_DEAD_CACHE_MAXN)
- {
- // get the next entry from head
- tb_list_entry_ref_t entry = tb_list_entry_head(&scheduler->coroutines_dead);
- tb_assert(entry);
-
- // remove it from the ready coroutines
- tb_list_entry_remove_head(&scheduler->coroutines_dead);
-
- // exit this coroutine
- tb_lo_coroutine_exit((tb_lo_coroutine_t*)tb_list_entry(&scheduler->coroutines_dead, entry));
- }
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // trace
- tb_trace_d("start %s", ok? "ok" : "no");
-
- // ok?
- return ok;
-}
-tb_void_t tb_lo_scheduler_resume(tb_lo_scheduler_t* scheduler, tb_lo_coroutine_t* coroutine)
-{
- // check
- tb_assert(scheduler && coroutine);
- tb_assert(tb_lo_core_state(coroutine) == TB_STATE_SUSPEND);
-
- // remove it from the suspend coroutines
- tb_list_entry_remove(&scheduler->coroutines_suspend, &coroutine->entry);
-
- // make it as ready
- tb_lo_scheduler_make_ready(scheduler, coroutine);
-}
-tb_lo_scheduler_ref_t tb_lo_scheduler_self_()
-{
-#ifndef TB_CONFIG_MICRO_ENABLE
- // get self scheduler on the current thread
- return (tb_lo_scheduler_ref_t)(s_scheduler_self_ex? s_scheduler_self_ex : tb_thread_local_get(&s_scheduler_self));
-#else
- return (tb_lo_scheduler_ref_t)s_scheduler_self_ex;
-#endif
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * public implementation
- */
-tb_lo_scheduler_ref_t tb_lo_scheduler_init()
-{
- // done
- tb_bool_t ok = tb_false;
- tb_lo_scheduler_t* scheduler = tb_null;
- do
- {
- // make scheduler
- scheduler = tb_malloc0_type(tb_lo_scheduler_t);
- tb_assert_and_check_break(scheduler);
-
- // init dead coroutines
- tb_list_entry_init(&scheduler->coroutines_dead, tb_lo_coroutine_t, entry, tb_null);
-
- // init ready coroutines
- tb_list_entry_init(&scheduler->coroutines_ready, tb_lo_coroutine_t, entry, tb_null);
-
- // init suspend coroutines
- tb_list_entry_init(&scheduler->coroutines_suspend, tb_lo_coroutine_t, entry, tb_null);
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (scheduler) tb_lo_scheduler_exit((tb_lo_scheduler_ref_t)scheduler);
- scheduler = tb_null;
- }
-
- // ok?
- return (tb_lo_scheduler_ref_t)scheduler;
-}
-tb_void_t tb_lo_scheduler_exit(tb_lo_scheduler_ref_t self)
-{
- // check
- tb_lo_scheduler_t* scheduler = (tb_lo_scheduler_t*)self;
- tb_assert_and_check_return(scheduler);
-
- // must be stopped
- tb_assert(scheduler->stopped);
-
- // exit io scheduler first
- if (scheduler->scheduler_io) tb_lo_scheduler_io_exit(scheduler->scheduler_io);
- scheduler->scheduler_io = tb_null;
-
- // check coroutines
- tb_assert(!tb_list_entry_size(&scheduler->coroutines_ready));
- tb_assert(!tb_list_entry_size(&scheduler->coroutines_suspend));
-
- // free all dead coroutines
- tb_lo_scheduler_free(&scheduler->coroutines_dead);
-
- // free all ready coroutines
- tb_lo_scheduler_free(&scheduler->coroutines_ready);
-
- // free all suspend coroutines
- tb_lo_scheduler_free(&scheduler->coroutines_suspend);
-
- // exit dead coroutines
- tb_list_entry_exit(&scheduler->coroutines_dead);
-
- // exit ready coroutines
- tb_list_entry_exit(&scheduler->coroutines_ready);
-
- // exit suspend coroutines
- tb_list_entry_exit(&scheduler->coroutines_suspend);
-
- // exit the scheduler
- tb_free(scheduler);
-}
-tb_void_t tb_lo_scheduler_kill(tb_lo_scheduler_ref_t self)
-{
- // check
- tb_lo_scheduler_t* scheduler = (tb_lo_scheduler_t*)self;
- tb_assert_and_check_return(scheduler);
-
- // stop it
- scheduler->stopped = tb_true;
-}
-tb_void_t tb_lo_scheduler_loop(tb_lo_scheduler_ref_t self, tb_bool_t exclusive)
-{
- // check
- tb_lo_scheduler_t* scheduler = (tb_lo_scheduler_t*)self;
- tb_assert_and_check_return(scheduler);
-
- // is exclusive mode?
- if (exclusive) s_scheduler_self_ex = scheduler;
-#ifndef TB_CONFIG_MICRO_ENABLE
- else
- {
- // init self scheduler local
- if (!tb_thread_local_init(&s_scheduler_self, tb_null)) return ;
-
- // update and overide the current scheduler
- tb_thread_local_set(&s_scheduler_self, self);
- }
-#else
- else
- {
- // trace
- tb_trace_e("non-exclusive is not suspported in micro mode!");
- }
-#endif
-
- // schedule all ready coroutines
- while (tb_list_entry_size(&scheduler->coroutines_ready) && !scheduler->stopped)
- {
- // trace
- tb_trace_d("[loop]: ready %lu", tb_list_entry_size(&scheduler->coroutines_ready));
-
- // get the next ready coroutine
- tb_lo_coroutine_t* coroutine_next = tb_lo_scheduler_next_ready(scheduler);
- tb_assert(coroutine_next);
-
- // process the running coroutine
- if (scheduler->running)
- {
- // get the state of running coroutine
- tb_size_t state = tb_lo_core_state(scheduler->running);
-
- // mark this coroutine as dead if the running coroutine(root level) have been finished
- if (state == TB_STATE_END)
- tb_lo_scheduler_make_dead(scheduler, scheduler->running);
- // suspend the running coroutine
- else if (state == TB_STATE_SUSPEND)
- tb_lo_scheduler_make_suspend(scheduler, scheduler->running);
- }
-
- // switch to it if the next coroutine (may be running coroutine) is ready
- if (tb_lo_core_state(coroutine_next) == TB_STATE_READY)
- tb_lo_scheduler_switch(scheduler, coroutine_next);
- }
-
- // stop it
- scheduler->stopped = tb_true;
-
- // is exclusive mode?
- if (exclusive) s_scheduler_self_ex = tb_null;
-#ifndef TB_CONFIG_MICRO_ENABLE
- else
- {
- // clear the current scheduler
- tb_thread_local_set(&s_scheduler_self, tb_null);
- }
-#endif
-}
-
diff --git a/core/src/tbox/src/tbox/coroutine/stackless/scheduler.h b/core/src/tbox/src/tbox/coroutine/stackless/scheduler.h
deleted file mode 100644
index a3d19c15d..000000000
--- a/core/src/tbox/src/tbox/coroutine/stackless/scheduler.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file scheduler.h
- * @ingroup coroutine
- *
- */
-#ifndef TB_COROUTINE_STACKLESS_SCHEDULER_H
-#define TB_COROUTINE_STACKLESS_SCHEDULER_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-/// the self scheduler
-#define tb_lo_scheduler_self() tb_lo_coroutine_scheduler_(co__)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init scheduler
- *
- * @return the scheduler
- */
-tb_lo_scheduler_ref_t tb_lo_scheduler_init(tb_noarg_t);
-
-/*! exit scheduler
- *
- * @param scheduler the scheduler
- */
-tb_void_t tb_lo_scheduler_exit(tb_lo_scheduler_ref_t scheduler);
-
-/* kill the scheduler
- *
- * @param scheduler the scheduler
- */
-tb_void_t tb_lo_scheduler_kill(tb_lo_scheduler_ref_t scheduler);
-
-/*! run the scheduler loop
- *
- * @param scheduler the scheduler
- * @param exclusive enable exclusive mode, we need ensure only one loop() be called at the same time,
- * but it will be faster using thr global scheduler instead of TLS storage
- */
-tb_void_t tb_lo_scheduler_loop(tb_lo_scheduler_ref_t scheduler, tb_bool_t exclusive);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/coroutine/stackless/semaphore.h b/core/src/tbox/src/tbox/coroutine/stackless/semaphore.h
deleted file mode 100644
index 495883b1b..000000000
--- a/core/src/tbox/src/tbox/coroutine/stackless/semaphore.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file semaphore.h
- * @ingroup coroutine
- *
- */
-#ifndef TB_COROUTINE_STACKLESS_SEMAPHORE_H
-#define TB_COROUTINE_STACKLESS_SEMAPHORE_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "coroutine.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-/*! init semaphore
- *
- * @param sem the semaphore pointer
- * @param val the initial semaphore value
- */
-#define tb_lo_semaphore_init(sem, val) (sem)->value = val
-
-/*! exit semaphore
- *
- * @param sem the semaphore pointer
- */
-#define tb_lo_semaphore_exit(sem) (sem)->value = 0
-
-/*! get semaphore value
- *
- * @param sem the semaphore pointer
- *
- * @return the semaphore value
- */
-#define tb_lo_semaphore_value(sem) ((sem)->value)
-
-/*! post semaphore
- *
- * @param sem the semaphore pointer
- * @param post the post semaphore value
- */
-#define tb_lo_semaphore_post(sem, post) \
-do \
-{ \
- (sem)->value += (post); \
- tb_lo_coroutine_yield(); \
- \
-} while (0)
-
-/*! wait semaphore
- *
- * @param sem the semaphore pointer
- */
-#define tb_lo_semaphore_wait(sem) \
-do \
-{ \
- tb_lo_coroutine_wait_until((sem)->value > 0); \
- (sem)->value--; \
- \
-} while(0)
-
-/*! try to wait semaphore
- *
- * @param sem the semaphore pointer
- *
- * @return tb_true or tb_false
- */
-#define tb_lo_semaphore_wait_try(sem) (((sem)->value > 0)? (sem)->value-- : 0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the stackless semaphore type
-typedef struct __tb_lo_semaphore_t
-{
- // the semaphore value
- tb_long_t value;
-
-}tb_lo_semaphore_t, *tb_lo_semaphore_ref_t;
-
-#endif
diff --git a/core/src/tbox/src/tbox/coroutine/stackless/stackless.h b/core/src/tbox/src/tbox/coroutine/stackless/stackless.h
deleted file mode 100644
index 9b0b5d916..000000000
--- a/core/src/tbox/src/tbox/coroutine/stackless/stackless.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file stackless.h
- * @ingroup coroutine
- *
- */
-#ifndef TB_COROUTINE_STACKLESS_H
-#define TB_COROUTINE_STACKLESS_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "coroutine.h"
-#include "scheduler.h"
-#include "semaphore.h"
-#include "lock.h"
-
-
-#endif
diff --git a/core/src/tbox/src/tbox/database/database.h b/core/src/tbox/src/tbox/database/database.h
deleted file mode 100644
index 1546e107b..000000000
--- a/core/src/tbox/src/tbox/database/database.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file database.h
- * @defgroup database
- */
-#ifndef TB_DATABASE_H
-#define TB_DATABASE_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-#include "sql.h"
-
-
-
-#endif
diff --git a/core/src/tbox/src/tbox/database/impl/mysql.c b/core/src/tbox/src/tbox/database/impl/mysql.c
deleted file mode 100644
index e0e4e5e19..000000000
--- a/core/src/tbox/src/tbox/database/impl/mysql.c
+++ /dev/null
@@ -1,1705 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file mysql.c
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "mysql"
-#define TB_TRACE_MODULE_DEBUG (1)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-#include <mysql.h>
-#include <errmsg.h>
-#include <mysqld_error.h>
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the mysql result row type
-typedef struct __tb_database_mysql_result_row_t
-{
- // the iterator
- tb_iterator_t itor;
-
- // the row
- MYSQL_ROW row;
-
- // the lengths
- tb_ulong_t* lengths;
-
- // the col count
- tb_size_t count;
-
- // the col value
- tb_database_sql_value_t value;
-
-}tb_database_mysql_result_row_t;
-
-// the mysql result type
-typedef struct __tb_database_mysql_result_t
-{
- // the iterator
- tb_iterator_t itor;
-
- // the statement
- MYSQL_STMT* statement;
-
- // the result
- MYSQL_RES* result;
-
- // the fields
- MYSQL_FIELD* fields;
-
- // the metadata
- MYSQL_RES* metadata;
-
- // the row count
- tb_size_t count;
-
- // try loading all?
- tb_bool_t try_all;
-
- // the row
- tb_database_mysql_result_row_t row;
-
- // the stream
- tb_stream_ref_t stream;
-
-}tb_database_mysql_result_t;
-
-// the mysql stream type
-typedef struct __tb_database_mysql_stream_impl_t
-{
- // the statement
- MYSQL_STMT* statement;
-
- // the result
- MYSQL_BIND* result;
-
- // the offset
- tb_size_t offset;
-
- // the column
- tb_size_t column;
-
-}tb_database_mysql_stream_impl_t;
-
-// the mysql type
-typedef struct __tb_database_mysql_t
-{
- // the base
- tb_database_sql_impl_t base;
-
- // the result
- tb_database_mysql_result_t result;
-
- // the database
- MYSQL* database;
-
- // the bind list
- MYSQL_BIND* bind_list;
-
- // the bind maxn
- tb_size_t bind_maxn;
-
- // the bind data
- tb_buffer_t bind_data;
-
-}tb_database_mysql_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * declaration
- */
-static tb_void_t tb_database_mysql_result_exit(tb_database_sql_impl_t* database, tb_iterator_ref_t result);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * library implementation
- */
-static tb_handle_t tb_database_mysql_library_init(tb_cpointer_t* ppriv)
-{
- // init it
- if (mysql_library_init(0, tb_null, tb_null))
- {
- // trace
- tb_trace_e("init: mysql library failed!");
- return tb_null;
- }
-
- // ok
- return ppriv;
-}
-static tb_void_t tb_database_mysql_library_exit(tb_handle_t handle, tb_cpointer_t priv)
-{
- // exit it
- mysql_library_end();
-}
-static tb_handle_t tb_database_mysql_library_load()
-{
- return tb_singleton_instance(TB_SINGLETON_TYPE_LIBRARY_MYSQL, tb_database_mysql_library_init, tb_database_mysql_library_exit, tb_null, tb_null);
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * state implementation
- */
-static tb_size_t tb_database_mysql_state_from_errno(tb_size_t errno)
-{
- // done
- tb_size_t state = TB_STATE_DATABASE_UNKNOWN_ERROR;
- switch (errno)
- {
- case ER_NO_DB_ERROR:
- case ER_BAD_DB_ERROR:
- state = TB_STATE_DATABASE_NO_SUCH_DATABASE;
- break;
- case ER_NO_SUCH_TABLE:
- state = TB_STATE_DATABASE_NO_SUCH_TABLE;
- break;
- case ER_BAD_FIELD_ERROR:
- state = TB_STATE_DATABASE_NO_SUCH_FIELD;
- break;
- case ER_ACCESS_DENIED_ERROR:
- state = TB_STATE_DATABASE_ACCESS_DENIED;
- break;
- case ER_PARSE_ERROR:
- state = TB_STATE_DATABASE_PARSE_ERROR;
- break;
- case ER_WRONG_VALUE_COUNT_ON_ROW:
- state = TB_STATE_DATABASE_VALUE_COUNT_ERROR;
- break;
- case CR_UNKNOWN_HOST:
- state = TB_STATE_DATABASE_UNKNOWN_HOST;
- break;
- case ER_UNKNOWN_ERROR:
- break;
- default:
- tb_trace_e("unknown errno: %lu", errno);
- break;
- }
-
- // ok?
- return state;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * stream implementation
- */
-static tb_bool_t tb_database_mysql_stream_impl_open(tb_stream_ref_t stream)
-{
- // check
- tb_database_mysql_stream_impl_t* impl = (tb_database_mysql_stream_impl_t*)stream;
- tb_assert_and_check_return_val(impl && impl->statement, tb_false);
-
- // check result
- tb_assert_and_check_return_val(impl->result && impl->result->buffer && impl->result->buffer_length, tb_false);
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_database_mysql_stream_impl_clos(tb_stream_ref_t stream)
-{
- // check
- tb_database_mysql_stream_impl_t* impl = (tb_database_mysql_stream_impl_t*)stream;
- tb_assert_and_check_return_val(impl, tb_false);
-
- // ok
- return tb_true;
-}
-static tb_long_t tb_database_mysql_stream_impl_read(tb_stream_ref_t stream, tb_byte_t* data, tb_size_t size)
-{
- // check
- tb_database_mysql_stream_impl_t* impl = (tb_database_mysql_stream_impl_t*)stream;
- tb_assert_and_check_return_val(impl && impl->statement, -1);
-
- // check data and size
- tb_check_return_val(data, -1);
- tb_check_return_val(size, 0);
-
- // check result
- tb_assert_and_check_return_val(impl->result && impl->result->buffer && impl->result->buffer_length, -1);
-
- // the length
- tb_size_t length = (tb_size_t)*impl->result->length;
-
- // end?
- tb_check_return_val(length && impl->offset < length, -1);
-
- // read data
- size = tb_min3(size, (tb_size_t)impl->result->buffer_length, length - impl->offset);
- if (size) tb_memcpy(data, impl->result->buffer, size);
-
- // update offset
- impl->offset += size;
-
- // fetch column
- if (mysql_stmt_fetch_column(impl->statement, impl->result, impl->column, impl->offset))
- {
- // trace
- tb_trace_e("stream: fetch failed at: %lu, error[%d]: %s", impl->column, mysql_stmt_errno(impl->statement), mysql_stmt_error(impl->statement));
- return -1;
- }
-
- // trace
-// tb_trace_d("stream: read: %lu", size);
-
- // ok?
- return (tb_long_t)(size);
-}
-static tb_long_t tb_database_mysql_stream_impl_wait(tb_stream_ref_t stream, tb_size_t wait, tb_long_t timeout)
-{
- // check
- tb_database_mysql_stream_impl_t* impl = (tb_database_mysql_stream_impl_t*)stream;
- tb_assert_and_check_return_val(impl, -1);
-
- // ok?
- return wait;
-}
-static tb_bool_t tb_database_mysql_stream_impl_ctrl(tb_stream_ref_t stream, tb_size_t ctrl, tb_va_list_t args)
-{
- // check
- tb_database_mysql_stream_impl_t* impl = (tb_database_mysql_stream_impl_t*)stream;
- tb_assert_and_check_return_val(impl, tb_false);
-
- // ctrl
- switch (ctrl)
- {
- case TB_STREAM_CTRL_GET_SIZE:
- {
- // the psize
- tb_hong_t* psize = (tb_hong_t*)tb_va_arg(args, tb_hong_t*);
- tb_assert_and_check_return_val(psize && impl->result, tb_false);
-
- // get size
- *psize = (tb_hong_t)*impl->result->length;
-
- // ok
- return tb_true;
- }
- default:
- break;
- }
- return tb_false;
-}
-static tb_stream_ref_t tb_database_mysql_stream_impl_init(MYSQL_STMT* statement, MYSQL_BIND* result, tb_size_t column)
-{
- // check
- tb_assert_and_check_return_val(statement && result, tb_null);
-
- // init stream
- tb_stream_ref_t stream = tb_stream_init( TB_STREAM_TYPE_NONE
- , sizeof(tb_database_mysql_stream_impl_t)
- , 0
- , tb_database_mysql_stream_impl_open
- , tb_database_mysql_stream_impl_clos
- , tb_null
- , tb_database_mysql_stream_impl_ctrl
- , tb_database_mysql_stream_impl_wait
- , tb_database_mysql_stream_impl_read
- , tb_null
- , tb_null
- , tb_null
- , tb_null);
- tb_assert_and_check_return_val(stream, tb_null);
-
- // init the stream impl
- tb_database_mysql_stream_impl_t* impl = (tb_database_mysql_stream_impl_t*)stream;
- if (impl)
- {
- impl->statement = statement;
- impl->result = result;
- impl->column = column;
- }
-
- // ok?
- return (tb_stream_ref_t)stream;
-}
-static tb_bool_t tb_database_mysql_stream_impl_set_value(tb_database_sql_value_t* value, tb_database_mysql_t* mysql, MYSQL_BIND* result, tb_size_t column)
-{
- // check
- tb_assert_and_check_return_val(value && mysql && mysql->result.statement && result, tb_false);
-
- // done
- tb_bool_t ok = tb_false;
- do
- {
- // exit the last stream first
- if (mysql->result.stream) tb_stream_exit(mysql->result.stream);
- mysql->result.stream = tb_null;
-
- // init stream
- mysql->result.stream = tb_database_mysql_stream_impl_init(mysql->result.statement, result, column);
- tb_assert_and_check_break(mysql->result.stream);
-
- // open stream
- if (!tb_stream_open(mysql->result.stream)) break;
-
- // set blob32
- tb_database_sql_value_set_blob32(value, tb_null, 0, mysql->result.stream);
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (mysql->result.stream) tb_stream_exit(mysql->result.stream);
- mysql->result.stream = tb_null;
- }
-
- // ok?
- return ok;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * iterator implementation
- */
-static tb_size_t tb_database_mysql_result_row_iterator_size(tb_iterator_ref_t iterator)
-{
- // check
- tb_database_mysql_result_t* result = (tb_database_mysql_result_t*)iterator;
- tb_assert(result);
-
- // size
- return result->count;
-}
-static tb_size_t tb_database_mysql_result_row_iterator_head(tb_iterator_ref_t iterator)
-{
- // head
- return 0;
-}
-static tb_size_t tb_database_mysql_result_row_iterator_tail(tb_iterator_ref_t iterator)
-{
- // check
- tb_database_mysql_result_t* result = (tb_database_mysql_result_t*)iterator;
- tb_assert(result);
-
- // tail
- return result->count;
-}
-static tb_size_t tb_database_mysql_result_row_iterator_prev(tb_iterator_ref_t iterator, tb_size_t itor)
-{
- // check
- tb_database_mysql_result_t* result = (tb_database_mysql_result_t*)iterator;
- tb_assert(result);
- tb_assert_and_check_return_val(itor && itor <= result->count, result->count);
-
- // load all?
- tb_assert_and_check_return_val(result->try_all, result->count);
-
- // prev
- return itor - 1;
-}
-static tb_size_t tb_database_mysql_result_row_iterator_next(tb_iterator_ref_t iterator, tb_size_t itor)
-{
- // check
- tb_database_mysql_result_t* result = (tb_database_mysql_result_t*)iterator;
- tb_assert(result);
- tb_assert_and_check_return_val(itor < result->count, result->count);
-
- // not load all? try fetching it
- if (!result->try_all)
- {
- // fetch statement
- if (result->statement)
- {
- // fetch the row
- tb_int_t ok = 0;
- if ((ok = mysql_stmt_fetch(result->statement)))
- {
- // end or error?
- if (ok != MYSQL_DATA_TRUNCATED)
- {
- // error?
- if (ok != MYSQL_NO_DATA)
- {
- // the mysql
- tb_database_mysql_t* mysql = (tb_database_mysql_t*)iterator->priv;
-
- // save state
- if (mysql) mysql->base.state = tb_database_mysql_state_from_errno(mysql_stmt_errno(result->statement));
-
- // trace
- tb_trace_e("statement: fetch row %lu failed, error[%d]: %s", itor, mysql_stmt_errno(result->statement), mysql_stmt_error(result->statement));
- }
-
- // end
- return result->count;
- }
- }
- }
- // fetch result
- else
- {
- // check
- tb_assert_and_check_return_val(result->result, result->count);
-
- // fetch the row
- result->row.row = mysql_fetch_row(result->result);
- tb_check_return_val(result->row.row, result->count);
-
- // fetch the lengths
- result->row.lengths = mysql_fetch_lengths(result->result);
- tb_assert_and_check_return_val(result->row.lengths, result->count);
- }
- }
-
- // next
- return itor + 1;
-}
-static tb_pointer_t tb_database_mysql_result_row_iterator_item(tb_iterator_ref_t iterator, tb_size_t itor)
-{
- // check
- tb_database_mysql_result_t* result = (tb_database_mysql_result_t*)iterator;
- tb_assert_and_check_return_val(result && itor < result->count, tb_null);
-
- // load all?
- if (result->try_all)
- {
- // load statement row
- if (result->statement)
- {
- // seek to the row number
- mysql_stmt_data_seek(result->statement, itor);
-
- // fetch the row
- tb_int_t ok = 0;
- if ((ok = mysql_stmt_fetch(result->statement)))
- {
- // end or error?
- if (ok != MYSQL_DATA_TRUNCATED)
- {
- // error?
- if (ok != MYSQL_NO_DATA)
- {
- // the mysql
- tb_database_mysql_t* mysql = (tb_database_mysql_t*)iterator->priv;
-
- // save state
- if (mysql) mysql->base.state = tb_database_mysql_state_from_errno(mysql_stmt_errno(result->statement));
-
- // trace
- tb_trace_e("statement: fetch row %lu failed, error[%d]: %s", itor, mysql_stmt_errno(result->statement), mysql_stmt_error(result->statement));
- }
- return tb_null;
- }
- }
- }
- // load result row
- else
- {
- // check
- tb_assert_and_check_return_val(result->result, tb_null);
-
- // seek to the row number
- mysql_data_seek(result->result, itor);
-
- // fetch the row
- result->row.row = mysql_fetch_row(result->result);
- tb_assert_and_check_return_val(result->row.row, tb_null);
-
- // fetch the lengths
- result->row.lengths = mysql_fetch_lengths(result->result);
- tb_assert_and_check_return_val(result->row.lengths, tb_null);
- }
- }
-
- // the row iterator
- return (tb_pointer_t)&result->row;
-}
-static tb_size_t tb_database_mysql_result_col_iterator_size(tb_iterator_ref_t iterator)
-{
- // check
- tb_database_mysql_result_row_t* row = (tb_database_mysql_result_row_t*)iterator;
- tb_assert_and_check_return_val(row, 0);
-
- // size
- return row->count;
-}
-static tb_size_t tb_database_mysql_result_col_iterator_head(tb_iterator_ref_t iterator)
-{
- // check
- tb_database_mysql_result_row_t* row = (tb_database_mysql_result_row_t*)iterator;
- tb_assert_and_check_return_val(row, 0);
-
- // head
- return 0;
-}
-static tb_size_t tb_database_mysql_result_col_iterator_tail(tb_iterator_ref_t iterator)
-{
- // check
- tb_database_mysql_result_row_t* row = (tb_database_mysql_result_row_t*)iterator;
- tb_assert_and_check_return_val(row, 0);
-
- // tail
- return row->count;
-}
-static tb_size_t tb_database_mysql_result_col_iterator_prev(tb_iterator_ref_t iterator, tb_size_t itor)
-{
- // check
- tb_database_mysql_result_row_t* row = (tb_database_mysql_result_row_t*)iterator;
- tb_assert_and_check_return_val(row && itor && itor <= row->count, 0);
-
- // prev
- return itor - 1;
-}
-static tb_size_t tb_database_mysql_result_col_iterator_next(tb_iterator_ref_t iterator, tb_size_t itor)
-{
- // check
- tb_database_mysql_result_row_t* row = (tb_database_mysql_result_row_t*)iterator;
- tb_assert_and_check_return_val(row && itor < row->count, row->count);
-
- // next
- return itor + 1;
-}
-static tb_pointer_t tb_database_mysql_result_col_iterator_item(tb_iterator_ref_t iterator, tb_size_t itor)
-{
- // check
- tb_database_mysql_result_row_t* row = (tb_database_mysql_result_row_t*)iterator;
- tb_assert_and_check_return_val(row && itor < row->count, tb_null);
-
- // the mysql
- tb_database_mysql_t* mysql = (tb_database_mysql_t*)iterator->priv;
- tb_assert_and_check_return_val(mysql && mysql->result.fields, tb_null);
-
- // the field
- MYSQL_FIELD* field = &mysql->result.fields[itor];
-
- // fetch column from statement
- if (mysql->result.statement)
- {
- // check
- tb_assert_and_check_return_val(mysql->bind_list && itor < mysql->bind_maxn, tb_null);
-
- // the result
- MYSQL_BIND* result = &mysql->bind_list[itor];
-
- // fetch column
- if (mysql_stmt_fetch_column(mysql->result.statement, result, itor, 0))
- {
- // save state
- mysql->base.state = tb_database_mysql_state_from_errno(mysql_stmt_errno(mysql->result.statement));
-
- // trace
- tb_trace_e("statement: fetch result failed at: %lu, field_type: %d, error[%d]: %s", itor, field->type, mysql_stmt_errno(mysql->result.statement), mysql_stmt_error(mysql->result.statement));
- return tb_null;
- }
-
- // init value
- tb_database_sql_value_name_set(&row->value, (tb_char_t const*)field->name);
- switch (result->buffer_type)
- {
- case MYSQL_TYPE_STRING:
- tb_database_sql_value_set_text(&row->value, (tb_char_t const*)result->buffer, (tb_size_t)*result->length);
- break;
- case MYSQL_TYPE_LONG:
- tb_database_sql_value_set_int32(&row->value, *((tb_int32_t const*)result->buffer));
- break;
- case MYSQL_TYPE_LONGLONG:
- tb_database_sql_value_set_int64(&row->value, *((tb_int64_t const*)result->buffer));
- break;
- case MYSQL_TYPE_SHORT:
- tb_database_sql_value_set_int16(&row->value, *((tb_int16_t const*)result->buffer));
- break;
- case MYSQL_TYPE_TINY:
- tb_database_sql_value_set_int8(&row->value, *((tb_int8_t const*)result->buffer));
- break;
- case MYSQL_TYPE_INT24:
- tb_database_sql_value_set_int32(&row->value, tb_bits_get_s24_ne((tb_byte_t const*)result->buffer));
- break;
- // note: the field type of text, tinyblob, blob and longblob always be blob
- case MYSQL_TYPE_BLOB:
- {
- // text?
- if (field->charsetnr != 63)
- {
- tb_database_sql_value_set_text(&row->value, (tb_char_t const*)result->buffer, (tb_size_t)*result->length);
- }
- // blob?
- else
- {
- // blob8?
- if ((tb_size_t)*result->length <= TB_MAXU8)
- {
- tb_database_sql_value_set_blob8(&row->value, (tb_byte_t const*)result->buffer, (tb_size_t)*result->length);
- }
- // blob16?
- else if ((tb_size_t)*result->length <= TB_MAXU16)
- {
- tb_database_sql_value_set_blob16(&row->value, (tb_byte_t const*)result->buffer, (tb_size_t)*result->length);
- }
- // blob32?
- else
- {
- tb_database_mysql_stream_impl_set_value(&row->value, mysql, result, itor);
- }
- }
- }
- break;
- case MYSQL_TYPE_LONG_BLOB:
- case MYSQL_TYPE_MEDIUM_BLOB:
- tb_database_mysql_stream_impl_set_value(&row->value, mysql, result, itor);
- break;
- case MYSQL_TYPE_TINY_BLOB:
- tb_database_sql_value_set_blob8(&row->value, (tb_byte_t const*)result->buffer, (tb_size_t)*result->length);
- break;
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- case MYSQL_TYPE_FLOAT:
- tb_database_sql_value_set_float(&row->value, *((tb_float_t const*)result->buffer));
- break;
- case MYSQL_TYPE_DOUBLE:
- tb_database_sql_value_set_double(&row->value, *((tb_double_t const*)result->buffer));
- break;
-#endif
- case MYSQL_TYPE_NULL:
- tb_database_sql_value_set_null(&row->value);
- break;
- case MYSQL_TYPE_DECIMAL:
- case MYSQL_TYPE_TIMESTAMP:
- case MYSQL_TYPE_DATE:
- case MYSQL_TYPE_TIME:
- case MYSQL_TYPE_DATETIME:
- case MYSQL_TYPE_YEAR:
- case MYSQL_TYPE_SET:
- case MYSQL_TYPE_ENUM:
- tb_trace_e("statement: fetch result: not supported buffer type: %d", result->buffer_type);
- return tb_null;
- default:
- tb_trace_e("statement: fetch result: unknown buffer type: %d", result->buffer_type);
- return tb_null;
- }
- }
- // fetch column from result
- else
- {
- // check
- tb_assert_and_check_return_val(row->row && row->lengths, tb_null);
-
- // init value
- tb_database_sql_value_name_set(&row->value, (tb_char_t const*)field->name);
- tb_database_sql_value_set_text(&row->value, (tb_char_t const*)row->row[itor], (tb_size_t)row->lengths[itor]);
- }
-
- // the col item
- return (tb_pointer_t)&row->value;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static __tb_inline__ tb_database_mysql_t* tb_database_mysql_cast(tb_database_sql_impl_t* database)
-{
- // check
- tb_assert_and_check_return_val(database && database->type == TB_DATABASE_SQL_TYPE_MYSQL, tb_null);
-
- // cast
- return (tb_database_mysql_t*)database;
-}
-static tb_bool_t tb_database_mysql_open(tb_database_sql_impl_t* database)
-{
- // check
- tb_database_mysql_t* mysql = tb_database_mysql_cast(database);
- tb_assert_and_check_return_val(mysql, tb_false);
-
- // done
- tb_bool_t ok = tb_false;
- tb_char_t const* host = tb_null;
- tb_size_t port = 0;
- tb_char_t username[64] = {0};
- tb_char_t password[64] = {0};
- tb_char_t database_sql_name[64] = {0};
- do
- {
- // the database host
- host = tb_url_host(&database->url);
- tb_assert_and_check_break(host);
-
- // the database port
- port = tb_url_port(&database->url);
-
- // the database args
- tb_char_t const* args = tb_url_args(&database->url);
- if (args)
- {
- // the args size
- tb_size_t argn = tb_strlen(args);
-
- // the database username
- tb_char_t const* p = tb_stristr(args, "username=");
- if (p)
- {
- // skip to value
- p += 9;
-
- // the value end
- tb_char_t const* e = tb_strchr(p, '&');
- if (!e) e = args + argn;
-
- // save username
- if (p < e) tb_strlcpy(username, p, tb_min((e - p) + 1, sizeof(username)));
- }
-
- // the database password
- p = tb_stristr(args, "password=");
- if (p)
- {
- // skip to value
- p += 9;
-
- // the value end
- tb_char_t const* e = tb_strchr(p, '&');
- if (!e) e = args + argn;
-
- // save password
- if (p < e) tb_strlcpy(password, p, tb_min((e - p) + 1, sizeof(password)));
- }
-
- // the database name
- p = tb_stristr(args, "database=");
- if (p)
- {
- // skip to value
- p += 9;
-
- // the value end
- tb_char_t const* e = tb_strchr(p, '&');
- if (!e) e = args + argn;
-
- // save database name
- if (p < e) tb_strlcpy(database_sql_name, p, tb_min((e - p) + 1, sizeof(database_sql_name)));
- }
- }
-
- // load mysql library
- if (!tb_database_mysql_library_load()) break;
-
- // init mysql database
- mysql->database = mysql_init(tb_null);
- tb_assert_and_check_break(mysql->database);
-
- // connect it
- if (!mysql_real_connect(mysql->database, host, username[0]? username : tb_null, password[0]? password : tb_null, database_sql_name[0]? database_sql_name : tb_null, (tb_uint_t)port, tb_null, 0))
- {
- // save state
- mysql->base.state = tb_database_mysql_state_from_errno(mysql_errno(mysql->database));
-
- // trace
- tb_trace_e("open: host: %s failed, error[%d]: %s", host, mysql_errno(mysql->database), mysql_error(mysql->database));
- break;
- }
-
- // disable auto commit
- if (mysql_autocommit(mysql->database, 0))
- {
- // save state
- mysql->base.state = tb_database_mysql_state_from_errno(mysql_errno(mysql->database));
-
- // trace
- tb_trace_e("open: disable auto commit failed, error[%d]: %s", mysql_errno(mysql->database), mysql_error(mysql->database));
- break;
- }
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // trace
- tb_trace_d("open: host: %s, port: %lu, username: %s, password: %s, database: %s : %s", host, port, username, password, database_sql_name, ok? "ok" : "no");
-
- // ok?
- return ok;
-}
-static tb_void_t tb_database_mysql_clos(tb_database_sql_impl_t* database)
-{
- // check
- tb_database_mysql_t* mysql = tb_database_mysql_cast(database);
- tb_assert_and_check_return(mysql);
-
- // clear bind data
- tb_buffer_clear(&mysql->bind_data);
-
- // clear bind list
- if (mysql->bind_list && mysql->bind_maxn)
- tb_memset(mysql->bind_list, 0, mysql->bind_maxn * sizeof(MYSQL_BIND));
-
- // close database
- if (mysql->database) mysql_close(mysql->database);
- mysql->database = tb_null;
-}
-static tb_void_t tb_database_mysql_exit(tb_database_sql_impl_t* database)
-{
- // check
- tb_database_mysql_t* mysql = tb_database_mysql_cast(database);
- tb_assert_and_check_return(mysql);
-
- // close it first
- tb_database_mysql_clos(database);
-
- // exit bind data
- tb_buffer_exit(&mysql->bind_data);
-
- // exit bind list
- if (mysql->bind_list) tb_free(mysql->bind_list);
- mysql->bind_list = tb_null;
- mysql->bind_maxn = 0;
-
- // exit url
- tb_url_exit(&database->url);
-
- // exit it
- tb_free(mysql);
-}
-/* begin mysql transaction
- *
- * @note
- * the default storage engine MyIASM do not support transaction
- * need enable InnoDB engine and set autocommit=0 if you want to use it
- */
-static tb_bool_t tb_database_mysql_begin(tb_database_sql_impl_t* database)
-{
- // check
- tb_database_mysql_t* mysql = tb_database_mysql_cast(database);
- tb_assert_and_check_return_val(mysql && mysql->database, tb_false);
-
- // done begin
- if (mysql_query(mysql->database, "begin;"))
- {
- // save state
- mysql->base.state = tb_database_mysql_state_from_errno(mysql_errno(mysql->database));
-
- // trace
- tb_trace_e("begin: failed, error[%d]: %s", mysql_errno(mysql->database), mysql_error(mysql->database));
- return tb_false;
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_database_mysql_commit(tb_database_sql_impl_t* database)
-{
- // check
- tb_database_mysql_t* mysql = tb_database_mysql_cast(database);
- tb_assert_and_check_return_val(mysql && mysql->database, tb_false);
-
- // done commit
- if (mysql_commit(mysql->database))
- {
- // save state
- mysql->base.state = tb_database_mysql_state_from_errno(mysql_errno(mysql->database));
-
- // trace
- tb_trace_e("commit: failed, error[%d]: %s", mysql_errno(mysql->database), mysql_error(mysql->database));
- return tb_false;
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_database_mysql_rollback(tb_database_sql_impl_t* database)
-{
- // check
- tb_database_mysql_t* mysql = tb_database_mysql_cast(database);
- tb_assert_and_check_return_val(mysql && mysql->database, tb_false);
-
- // done rollback
- if (mysql_rollback(mysql->database))
- {
- // save state
- mysql->base.state = tb_database_mysql_state_from_errno(mysql_errno(mysql->database));
-
- // trace
- tb_trace_e("rollback: failed, error[%d]: %s", mysql_errno(mysql->database), mysql_error(mysql->database));
- return tb_false;
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_database_mysql_done(tb_database_sql_impl_t* database, tb_char_t const* sql)
-{
- // check
- tb_database_mysql_t* mysql = tb_database_mysql_cast(database);
- tb_assert_and_check_return_val(mysql && mysql->database && sql, tb_false);
-
- // exit the last result first
- tb_database_mysql_result_exit(database, (tb_iterator_ref_t)&mysql->result);
-
- // done query
- if (mysql_query(mysql->database, sql))
- {
- // save state
- mysql->base.state = tb_database_mysql_state_from_errno(mysql_errno(mysql->database));
-
- // trace
- tb_trace_e("done: sql: %s failed, error[%d]: %s", sql, mysql_errno(mysql->database), mysql_error(mysql->database));
- return tb_false;
- }
-
- // trace
- tb_trace_d("done: sql: %s: ok", sql);
-
- // ok
- return tb_true;
-}
-static tb_void_t tb_database_mysql_result_exit(tb_database_sql_impl_t* database, tb_iterator_ref_t result)
-{
- // check
- tb_database_mysql_result_t* mysql_result = (tb_database_mysql_result_t*)result;
- tb_assert_and_check_return(mysql_result);
-
- // exit stream
- if (mysql_result->stream) tb_stream_exit(mysql_result->stream);
- mysql_result->stream = tb_null;
-
- // exit result
- if (mysql_result->result) mysql_free_result(mysql_result->result);
- mysql_result->result = tb_null;
- mysql_result->fields = tb_null;
-
- // clear result
- mysql_result->count = 0;
- mysql_result->row.count = 0;
-
- // exit metadata
- if (mysql_result->metadata) mysql_free_result(mysql_result->metadata);
- mysql_result->metadata = tb_null;
-
- // clear statement
- if (mysql_result->statement && mysql_result->try_all)
- mysql_stmt_free_result(mysql_result->statement);
- mysql_result->statement = tb_null;
-
- // reset try all
- mysql_result->try_all = tb_false;
-}
-static tb_size_t tb_database_mysql_result_type_size(tb_size_t type)
-{
- // done
- tb_size_t size = 0;
- switch (type)
- {
- case MYSQL_TYPE_STRING: size = 8192; break;
- case MYSQL_TYPE_LONG: size = 4; break;
- case MYSQL_TYPE_LONGLONG: size = 8; break;
- case MYSQL_TYPE_SHORT: size = 2; break;
- case MYSQL_TYPE_TINY: size = 1; break;
- case MYSQL_TYPE_INT24: size = 3; break;
- // TODO: for text and tinyblob
- case MYSQL_TYPE_BLOB:
- case MYSQL_TYPE_MEDIUM_BLOB:
- case MYSQL_TYPE_LONG_BLOB: size = 65536; break;
- case MYSQL_TYPE_TINY_BLOB: size = 256; break;
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- case MYSQL_TYPE_FLOAT: size = 4; break;
- case MYSQL_TYPE_DOUBLE: size = 8; break;
-#endif
- case MYSQL_TYPE_NULL: break;
- case MYSQL_TYPE_DECIMAL:
- case MYSQL_TYPE_TIMESTAMP:
- case MYSQL_TYPE_DATE:
- case MYSQL_TYPE_TIME:
- case MYSQL_TYPE_DATETIME:
- case MYSQL_TYPE_YEAR:
- case MYSQL_TYPE_SET:
- case MYSQL_TYPE_ENUM:
- tb_trace_e("not supported field type: %d", type);
- break;
- default:
- tb_trace_e("unknown field type: %d", type);
- break;
- }
-
- // ok?
- return size;
-}
-static tb_size_t tb_database_mysql_result_bind_maxn(tb_database_mysql_t* mysql)
-{
- // check
- tb_assert_and_check_return_val(mysql && mysql->result.statement && mysql->result.fields, 0);
-
- // walk
- tb_size_t i = 0;
- tb_size_t m = 0;
- tb_size_t n = mysql->result.row.count;
- for (i = 0; i < n; i++)
- {
- // += buffer
- m += tb_database_mysql_result_type_size(mysql->result.fields[i].type);
-
- // += length
- m += sizeof(tb_ulong_t);
-
- // += is_null
- m += sizeof(my_bool);
- }
-
- // ok?
- return m;
-}
-static tb_bool_t tb_database_mysql_result_bind_data(tb_database_mysql_t* mysql)
-{
- // check
- tb_assert_and_check_return_val(mysql && mysql->result.statement && mysql->result.fields, tb_false);
-
- // done
- tb_bool_t ok = tb_false;
- do
- {
- // check
- tb_assert_and_check_break(mysql->bind_list && mysql->result.row.count <= mysql->bind_maxn);
-
- // the bind data and maxn
- tb_byte_t* bind_data = tb_buffer_data(&mysql->bind_data);
- tb_size_t bind_maxn = tb_buffer_maxn(&mysql->bind_data);
- tb_assert_and_check_break(bind_data && bind_maxn);
-
- // clear data
- tb_memset(bind_data, 0, bind_maxn);
-
- // bind data
- tb_size_t i = 0;
- tb_size_t n = mysql->result.row.count;
- tb_byte_t* p = bind_data;
- tb_byte_t* e = bind_data + bind_maxn;
- for (i = 0; i < n; i++)
- {
- // the bind
- MYSQL_BIND* bind = &mysql->bind_list[i];
-
- // bind type
- bind->buffer_type = mysql->result.fields[i].type;
-
- // bind buffer length
- bind->buffer_length = (tb_ulong_t)tb_database_mysql_result_type_size(bind->buffer_type);
-
- // bind buffer
- tb_assert_and_check_break(p + bind->buffer_length < e);
- bind->buffer = bind->buffer_length? (tb_char_t*)p : tb_null;
- p += bind->buffer_length;
-
- // bind is_unsigned
- bind->is_unsigned = (mysql->result.fields[i].flags & UNSIGNED_FLAG)? 1 : 0;
-
- // bind length
- tb_assert_and_check_break(p + sizeof(tb_ulong_t) < e);
- bind->length = (tb_ulong_t*)p;
- p += sizeof(tb_ulong_t);
-
- // bind is_null
- tb_assert_and_check_break(p + sizeof(my_bool) < e);
- bind->is_null = (my_bool*)p;
- p += sizeof(my_bool);
- }
-
- // check
- tb_assert_and_check_break(i == n);
-
- // bind result
- if (mysql_stmt_bind_result(mysql->result.statement, mysql->bind_list))
- {
- // save state
- mysql->base.state = tb_database_mysql_state_from_errno(mysql_stmt_errno(mysql->result.statement));
-
- // trace
- tb_trace_e("statement: bind result failed, error[%d]: %s", mysql_stmt_errno(mysql->result.statement), mysql_stmt_error(mysql->result.statement));
- break;
- }
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // ok?
- return ok;
-}
-static tb_bool_t tb_database_mysql_result_bind(tb_database_mysql_t* mysql, tb_bool_t try_all)
-{
- // check
- tb_assert_and_check_return_val(mysql && mysql->result.statement, tb_false);
-
- // done
- tb_bool_t ok = tb_false;
- do
- {
- // load the field infos
- mysql->result.metadata = mysql_stmt_result_metadata(mysql->result.statement);
- tb_check_break(mysql->result.metadata);
-
- // save result col count
- mysql->result.row.count = (tb_size_t)mysql_num_fields(mysql->result.metadata);
- tb_assert_and_check_break(mysql->result.row.count);
-
- // load result fields
- mysql->result.fields = mysql_fetch_fields(mysql->result.metadata);
- tb_assert_and_check_break(mysql->result.fields);
-
- // make bind list
- if (!mysql->bind_list)
- {
- mysql->bind_maxn = mysql->result.row.count + 16;
- mysql->bind_list = (MYSQL_BIND*)tb_nalloc(mysql->bind_maxn, sizeof(MYSQL_BIND));
- }
- // grow bind list
- else if (mysql->result.row.count > mysql->bind_maxn)
- {
- mysql->bind_maxn = mysql->result.row.count + 16;
- mysql->bind_list = (MYSQL_BIND*)tb_ralloc(mysql->bind_list, mysql->bind_maxn * sizeof(MYSQL_BIND));
- }
-
- // check
- tb_assert_and_check_break(mysql->bind_list && mysql->result.row.count <= mysql->bind_maxn);
-
- // clear bind list
- tb_memset(mysql->bind_list, 0, mysql->bind_maxn * sizeof(MYSQL_BIND));
-
- // compute bind maxn
- tb_size_t bind_maxn = tb_database_mysql_result_bind_maxn(mysql);
- tb_assert_and_check_break(bind_maxn);
-
- // resize bind data
- if (!tb_buffer_resize(&mysql->bind_data, bind_maxn)) break;
-
- // bind result data
- if (!tb_database_mysql_result_bind_data(mysql)) break;
-
- // load all?
- if (try_all && mysql_stmt_store_result(mysql->result.statement))
- {
- // save state
- mysql->base.state = tb_database_mysql_state_from_errno(mysql_stmt_errno(mysql->result.statement));
-
- // trace
- tb_trace_e("statement: load all result failed, error[%d]: %s", mysql_stmt_errno(mysql->result.statement), mysql_stmt_error(mysql->result.statement));
- break;
- }
-
- // try loading all?
- mysql->result.try_all = try_all;
-
- // save result row count
- mysql->result.count = try_all? (tb_size_t)mysql_stmt_num_rows(mysql->result.statement) : -1;
-
- // init mode
- mysql->result.itor.mode = (try_all? TB_ITERATOR_MODE_RACCESS : TB_ITERATOR_MODE_FORWARD) | TB_ITERATOR_MODE_READONLY;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // ok?
- return ok;
-}
-static tb_iterator_ref_t tb_database_mysql_result_load(tb_database_sql_impl_t* database, tb_bool_t try_all)
-{
- // check
- tb_database_mysql_t* mysql = tb_database_mysql_cast(database);
- tb_assert_and_check_return_val(mysql && mysql->database, tb_null);
-
- // done
- tb_bool_t ok = tb_false;
- do
- {
- // load result from statement
- if (mysql->result.statement)
- {
- // bind result
- if (!tb_database_mysql_result_bind(mysql, try_all)) break;
-
- // try fetching the first result
- if (!try_all)
- {
- // fetch the first row
- tb_int_t ok = 0;
- if ((ok = mysql_stmt_fetch(mysql->result.statement)))
- {
- // end or error?
- if (ok != MYSQL_DATA_TRUNCATED)
- {
- // error?
- if (ok != MYSQL_NO_DATA)
- {
- // save state
- mysql->base.state = tb_database_mysql_state_from_errno(mysql_stmt_errno(mysql->result.statement));
-
- // trace
- tb_trace_e("statement: fetch row head failed, error[%d]: %s", mysql_stmt_errno(mysql->result.statement), mysql_stmt_error(mysql->result.statement));
- }
- break;
- }
- }
- }
- }
- else
- {
- // load result
- mysql->result.result = try_all? mysql_store_result(mysql->database) : mysql_use_result(mysql->database);
- tb_check_break(mysql->result.result);
-
- // try fetching the first result
- if (!try_all)
- {
- // fetch the first row
- mysql->result.row.row = mysql_fetch_row(mysql->result.result);
- tb_check_break(mysql->result.row.row);
-
- // fetch the first lengths
- mysql->result.row.lengths = mysql_fetch_lengths(mysql->result.result);
- tb_assert_and_check_break(mysql->result.row.lengths);
- }
-
- // load result fields
- mysql->result.fields = mysql_fetch_fields(mysql->result.result);
- tb_assert_and_check_break(mysql->result.fields);
-
- // save result row count
- mysql->result.count = try_all? (tb_size_t)mysql_num_rows(mysql->result.result) : -1;
-
- // save result col count
- mysql->result.row.count = (tb_size_t)mysql_num_fields(mysql->result.result);
-
- // try loading all?
- mysql->result.try_all = try_all;
-
- // init mode
- mysql->result.itor.mode = (try_all? TB_ITERATOR_MODE_RACCESS : TB_ITERATOR_MODE_FORWARD) | TB_ITERATOR_MODE_READONLY;
- }
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit result
- tb_database_mysql_result_exit(database, (tb_iterator_ref_t)&mysql->result);
- }
-
- // ok?
- return ok? (tb_iterator_ref_t)&mysql->result : tb_null;
-}
-static tb_database_sql_statement_ref_t tb_database_mysql_statement_init(tb_database_sql_impl_t* database, tb_char_t const* sql)
-{
- // check
- tb_database_mysql_t* mysql = tb_database_mysql_cast(database);
- tb_assert_and_check_return_val(mysql && mysql->database && sql, tb_null);
-
- // done
- tb_bool_t ok = tb_false;
- MYSQL_STMT* statement = tb_null;
- do
- {
- // init statement
- statement = mysql_stmt_init(mysql->database);
- if (!statement)
- {
- // save state
- mysql->base.state = tb_database_mysql_state_from_errno(mysql_errno(mysql->database));
-
- // trace
- tb_trace_e("statement: init: %s failed, error[%d]: %s", sql, mysql_errno(mysql->database), mysql_error(mysql->database));
- break;
- }
-
- // prepare statement
- if (mysql_stmt_prepare(statement, sql, tb_strlen(sql)))
- {
- // save state
- mysql->base.state = tb_database_mysql_state_from_errno(mysql_stmt_errno(statement));
-
- // trace
- tb_trace_e("statement: prepare: %s failed, error[%d]: %s", sql, mysql_stmt_errno(statement), mysql_stmt_error(statement));
- break;
- }
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (statement) mysql_stmt_close(statement);
- statement = tb_null;
- }
-
- // ok?
- return (tb_database_sql_statement_ref_t)statement;
-}
-static tb_void_t tb_database_mysql_statement_exit(tb_database_sql_impl_t* database, tb_database_sql_statement_ref_t statement)
-{
- // exit it
- if (statement) mysql_stmt_close((MYSQL_STMT*)statement);
-}
-static tb_bool_t tb_database_mysql_statement_done(tb_database_sql_impl_t* database, tb_database_sql_statement_ref_t statement)
-{
- // check
- tb_database_mysql_t* mysql = tb_database_mysql_cast(database);
- tb_assert_and_check_return_val(mysql && mysql->database && statement, tb_false);
-
- // done
- tb_bool_t ok = tb_false;
- do
- {
- // exit the last result first
- tb_database_mysql_result_exit(database, (tb_iterator_ref_t)&mysql->result);
-
- // done statement
- if (mysql_stmt_execute((MYSQL_STMT*)statement))
- {
- // save state
- mysql->base.state = tb_database_mysql_state_from_errno(mysql_stmt_errno((MYSQL_STMT*)statement));
-
- // trace
- tb_trace_e("statement: done failed, error[%d]: %s", mysql_stmt_errno((MYSQL_STMT*)statement), mysql_stmt_error((MYSQL_STMT*)statement));
- break;
- }
-
- // save statement
- mysql->result.statement = (MYSQL_STMT*)statement;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // ok?
- return ok;
-}
-static tb_bool_t tb_database_mysql_statement_bind(tb_database_sql_impl_t* database, tb_database_sql_statement_ref_t statement, tb_database_sql_value_t const* list, tb_size_t size)
-{
- // check
- tb_database_mysql_t* mysql = tb_database_mysql_cast(database);
- tb_assert_and_check_return_val(mysql && mysql->database && statement && list && size, tb_false);
-
- // done
- tb_bool_t ok = tb_false;
- do
- {
- // check the param count
- tb_size_t param_count = mysql_stmt_param_count((MYSQL_STMT*)statement);
- tb_assert_and_check_break(size == param_count);
-
- // make bind list
- if (!mysql->bind_list)
- {
- mysql->bind_maxn = size + 16;
- mysql->bind_list = (MYSQL_BIND*)tb_nalloc(mysql->bind_maxn, sizeof(MYSQL_BIND));
- }
- // grow bind list
- else if (size > mysql->bind_maxn)
- {
- mysql->bind_maxn = size + 16;
- mysql->bind_list = (MYSQL_BIND*)tb_ralloc(mysql->bind_list, mysql->bind_maxn * sizeof(MYSQL_BIND));
- }
-
- // check
- tb_assert_and_check_break(mysql->bind_list && size <= mysql->bind_maxn);
-
- // clear bind list
- tb_memset(mysql->bind_list, 0, mysql->bind_maxn * sizeof(MYSQL_BIND));
-
- // init bind list
- tb_size_t i = 0;
- for (i = 0; i < size; i++)
- {
- // the value
- tb_database_sql_value_t const* value = &list[i];
- switch (value->type)
- {
- case TB_DATABASE_SQL_VALUE_TYPE_TEXT:
- mysql->bind_list[i].buffer_type = MYSQL_TYPE_STRING;
- mysql->bind_list[i].buffer = (tb_char_t*)tb_database_sql_value_text(value);
- mysql->bind_list[i].buffer_length = tb_database_sql_value_size(value) + 1;
- break;
- case TB_DATABASE_SQL_VALUE_TYPE_INT64:
- mysql->bind_list[i].buffer_type = MYSQL_TYPE_LONGLONG;
- mysql->bind_list[i].buffer = (tb_char_t*)&value->u.i64;
- break;
- case TB_DATABASE_SQL_VALUE_TYPE_INT32:
- mysql->bind_list[i].buffer_type = MYSQL_TYPE_LONG;
- mysql->bind_list[i].buffer = (tb_char_t*)&value->u.i32;
- break;
- case TB_DATABASE_SQL_VALUE_TYPE_INT16:
- mysql->bind_list[i].buffer_type = MYSQL_TYPE_SHORT;
- mysql->bind_list[i].buffer = (tb_char_t*)&value->u.i16;
- break;
- case TB_DATABASE_SQL_VALUE_TYPE_INT8:
- mysql->bind_list[i].buffer_type = MYSQL_TYPE_TINY;
- mysql->bind_list[i].buffer = (tb_char_t*)&value->u.i8;
- break;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT64:
- mysql->bind_list[i].buffer_type = MYSQL_TYPE_LONGLONG;
- mysql->bind_list[i].buffer = (tb_char_t*)&value->u.u64;
- mysql->bind_list[i].is_unsigned = 1;
- break;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT32:
- mysql->bind_list[i].buffer_type = MYSQL_TYPE_LONG;
- mysql->bind_list[i].buffer = (tb_char_t*)&value->u.u32;
- mysql->bind_list[i].is_unsigned = 1;
- break;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT16:
- mysql->bind_list[i].buffer_type = MYSQL_TYPE_SHORT;
- mysql->bind_list[i].buffer = (tb_char_t*)&value->u.u16;
- mysql->bind_list[i].is_unsigned = 1;
- break;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT8:
- mysql->bind_list[i].buffer_type = MYSQL_TYPE_TINY;
- mysql->bind_list[i].buffer = (tb_char_t*)&value->u.u8;
- mysql->bind_list[i].is_unsigned = 1;
- break;
- case TB_DATABASE_SQL_VALUE_TYPE_BLOB32:
- mysql->bind_list[i].buffer_type = MYSQL_TYPE_LONG_BLOB;
- mysql->bind_list[i].buffer = (tb_char_t*)tb_database_sql_value_blob(value);
- mysql->bind_list[i].buffer_length = tb_database_sql_value_size(value);
- mysql->bind_list[i].length = &mysql->bind_list[i].buffer_length;
- break;
- case TB_DATABASE_SQL_VALUE_TYPE_BLOB16:
- mysql->bind_list[i].buffer_type = MYSQL_TYPE_BLOB;
- mysql->bind_list[i].buffer = (tb_char_t*)tb_database_sql_value_blob(value);
- mysql->bind_list[i].buffer_length = tb_database_sql_value_size(value);
- mysql->bind_list[i].length = &mysql->bind_list[i].buffer_length;
- break;
- case TB_DATABASE_SQL_VALUE_TYPE_BLOB8:
- mysql->bind_list[i].buffer_type = MYSQL_TYPE_TINY_BLOB;
- mysql->bind_list[i].buffer = (tb_char_t*)tb_database_sql_value_blob(value);
- mysql->bind_list[i].buffer_length = tb_database_sql_value_size(value);
- mysql->bind_list[i].length = &mysql->bind_list[i].buffer_length;
- break;
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- case TB_DATABASE_SQL_VALUE_TYPE_FLOAT:
- mysql->bind_list[i].buffer_type = MYSQL_TYPE_FLOAT;
- mysql->bind_list[i].buffer = (tb_char_t*)&value->u.f;
- break;
- case TB_DATABASE_SQL_VALUE_TYPE_DOUBLE:
- mysql->bind_list[i].buffer_type = MYSQL_TYPE_DOUBLE;
- mysql->bind_list[i].buffer = (tb_char_t*)&value->u.d;
- break;
-#endif
- case TB_DATABASE_SQL_VALUE_TYPE_NULL:
- mysql->bind_list[i].buffer_type = MYSQL_TYPE_NULL;
- break;
- default:
- tb_trace_e("statement: bind: unknown value type: %lu", value->type);
- break;
- }
- }
-
- // bind it
- if (mysql_stmt_bind_param((MYSQL_STMT*)statement, mysql->bind_list))
- {
- // save state
- mysql->base.state = tb_database_mysql_state_from_errno(mysql_stmt_errno((MYSQL_STMT*)statement));
-
- // trace
- tb_trace_e("statement: bind failed, error[%d]: %s", mysql_stmt_errno((MYSQL_STMT*)statement), mysql_stmt_error((MYSQL_STMT*)statement));
- break;
- }
-
- // send blob32 data
- tb_byte_t data[TB_STREAM_BLOCK_MAXN];
- for (i = 0; i < size; i++)
- {
- // the value
- tb_database_sql_value_t const* value = &list[i];
- if (value->type == TB_DATABASE_SQL_VALUE_TYPE_BLOB32 && value->u.blob.stream)
- {
- // trace
- tb_trace_d("statement: bind: send: blob: %lld: ..", tb_stream_size(value->u.blob.stream));
-
- // done
- while (!tb_stream_beof(value->u.blob.stream))
- {
- // read it
- tb_long_t real = tb_stream_read(value->u.blob.stream, data, sizeof(data));
- if (real > 0)
- {
- // send it
- if (mysql_stmt_send_long_data((MYSQL_STMT*)statement, i, (tb_char_t const*)data, real))
- {
- // save state
- mysql->base.state = tb_database_mysql_state_from_errno(mysql_stmt_errno((MYSQL_STMT*)statement));
-
- // trace
- tb_trace_e("statement: bind: send blob data failed, error[%d]: %s", mysql_stmt_errno((MYSQL_STMT*)statement), mysql_stmt_error((MYSQL_STMT*)statement));
- break;
- }
- }
- else if (!real)
- {
- // wait
- tb_long_t wait = tb_stream_wait(value->u.blob.stream, TB_STREAM_WAIT_READ, tb_stream_timeout(value->u.blob.stream));
- tb_assert_and_check_break(wait > 0);
- }
- else break;
- }
- }
- }
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // ok?
- return ok;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-tb_size_t tb_database_mysql_probe(tb_url_ref_t url)
-{
- // check
- tb_assert_and_check_return_val(url, 0);
-
- // done
- tb_size_t score = 0;
- do
- {
- // the url arguments
- tb_char_t const* args = tb_url_args(url);
- if (args)
- {
- // find the database type
- tb_char_t const* ptype = tb_stristr(args, "type=");
- if (ptype && !tb_strnicmp(ptype + 5, "mysql", 5))
- {
- // ok
- score = 100;
- break;
- }
- }
-
- // the database port, the default port: 3306
- if (tb_url_port(url) == 3306) score += 20;
-
- // is sql url?
- if (tb_url_protocol(url) == TB_URL_PROTOCOL_SQL)
- score += 5;
-
- } while (0);
-
- // trace
- tb_trace_d("probe: %s, score: %lu", tb_url_cstr((tb_url_ref_t)url), score);
-
- // ok?
- return score;
-}
-tb_database_sql_ref_t tb_database_mysql_init(tb_url_ref_t url)
-{
- // check
- tb_assert_and_check_return_val(url, tb_null);
-
- // done
- tb_bool_t ok = tb_false;
- tb_database_mysql_t* mysql = tb_null;
- do
- {
- // make database
- mysql = tb_malloc0_type(tb_database_mysql_t);
- tb_assert_and_check_break(mysql);
-
- // init database
- mysql->base.type = TB_DATABASE_SQL_TYPE_MYSQL;
- mysql->base.open = tb_database_mysql_open;
- mysql->base.clos = tb_database_mysql_clos;
- mysql->base.exit = tb_database_mysql_exit;
- mysql->base.done = tb_database_mysql_done;
- mysql->base.begin = tb_database_mysql_begin;
- mysql->base.commit = tb_database_mysql_commit;
- mysql->base.rollback = tb_database_mysql_rollback;
- mysql->base.result_load = tb_database_mysql_result_load;
- mysql->base.result_exit = tb_database_mysql_result_exit;
- mysql->base.statement_init = tb_database_mysql_statement_init;
- mysql->base.statement_exit = tb_database_mysql_statement_exit;
- mysql->base.statement_done = tb_database_mysql_statement_done;
- mysql->base.statement_bind = tb_database_mysql_statement_bind;
-
- // init result row iterator
- mysql->result.itor.mode = TB_ITERATOR_MODE_RACCESS | TB_ITERATOR_MODE_READONLY;
- mysql->result.itor.priv = (tb_pointer_t)mysql;
- mysql->result.itor.step = 0;
- mysql->result.itor.size = tb_database_mysql_result_row_iterator_size;
- mysql->result.itor.head = tb_database_mysql_result_row_iterator_head;
- mysql->result.itor.tail = tb_database_mysql_result_row_iterator_tail;
- mysql->result.itor.prev = tb_database_mysql_result_row_iterator_prev;
- mysql->result.itor.next = tb_database_mysql_result_row_iterator_next;
- mysql->result.itor.item = tb_database_mysql_result_row_iterator_item;
- mysql->result.itor.copy = tb_null;
- mysql->result.itor.comp = tb_null;
-
- // init result col iterator
- mysql->result.row.itor.mode = TB_ITERATOR_MODE_RACCESS | TB_ITERATOR_MODE_READONLY;
- mysql->result.row.itor.priv = (tb_pointer_t)mysql;
- mysql->result.row.itor.step = 0;
- mysql->result.row.itor.size = tb_database_mysql_result_col_iterator_size;
- mysql->result.row.itor.head = tb_database_mysql_result_col_iterator_head;
- mysql->result.row.itor.tail = tb_database_mysql_result_col_iterator_tail;
- mysql->result.row.itor.prev = tb_database_mysql_result_col_iterator_prev;
- mysql->result.row.itor.next = tb_database_mysql_result_col_iterator_next;
- mysql->result.row.itor.item = tb_database_mysql_result_col_iterator_item;
- mysql->result.row.itor.copy = tb_null;
- mysql->result.row.itor.comp = tb_null;
-
- // init url
- if (!tb_url_init(&mysql->base.url)) break;
-
- // copy url
- tb_url_copy(&mysql->base.url, url);
-
- // init state
- mysql->base.state = TB_STATE_OK;
-
- // init bind
- if (!tb_buffer_init(&mysql->bind_data)) break;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit database
- if (mysql) tb_database_mysql_exit((tb_database_sql_impl_t*)mysql);
- mysql = tb_null;
- }
-
- // ok?
- return (tb_database_sql_ref_t)mysql;
-}
-
diff --git a/core/src/tbox/src/tbox/database/impl/mysql.h b/core/src/tbox/src/tbox/database/impl/mysql.h
deleted file mode 100644
index 2856df9ec..000000000
--- a/core/src/tbox/src/tbox/database/impl/mysql.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file mysql.h
- */
-#ifndef TB_DATABASE_IMPL_MYSQL_H
-#define TB_DATABASE_IMPL_MYSQL_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/* probe mysql from the url
- *
- * @param url the database url
- *
- * @return the score
- */
-tb_size_t tb_database_mysql_probe(tb_url_ref_t url);
-
-/* init mysql
- *
- * @param url the database url
- *
- * @return the database handle
- */
-tb_database_sql_ref_t tb_database_mysql_init(tb_url_ref_t url);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/database/impl/prefix.h b/core/src/tbox/src/tbox/database/impl/prefix.h
deleted file mode 100644
index 071678ed6..000000000
--- a/core/src/tbox/src/tbox/database/impl/prefix.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file prefix.h
- *
- */
-#ifndef TB_DATABASE_IMPL_PREFIX_H
-#define TB_DATABASE_IMPL_PREFIX_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "../prefix.h"
-#include "../sql.h"
-#include "sqlite3.h"
-#include "mysql.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the database sql impl type
-typedef struct __tb_database_sql_impl_t
-{
- // the url
- tb_url_t url;
-
- // the type
- tb_size_t type;
-
- // the state
- tb_size_t state;
-
- // is opened?
- tb_bool_t bopened;
-
- // open
- tb_bool_t (*open)(struct __tb_database_sql_impl_t* database);
-
- // clos
- tb_void_t (*clos)(struct __tb_database_sql_impl_t* database);
-
- // exit
- tb_void_t (*exit)(struct __tb_database_sql_impl_t* database);
-
- // done
- tb_bool_t (*done)(struct __tb_database_sql_impl_t* database, tb_char_t const* sql);
-
- // begin
- tb_bool_t (*begin)(struct __tb_database_sql_impl_t* database);
-
- // commit
- tb_bool_t (*commit)(struct __tb_database_sql_impl_t* database);
-
- // rollback
- tb_bool_t (*rollback)(struct __tb_database_sql_impl_t* database);
-
- // load result
- tb_iterator_ref_t (*result_load)(struct __tb_database_sql_impl_t* database, tb_bool_t try_all);
-
- // exit result
- tb_void_t (*result_exit)(struct __tb_database_sql_impl_t* database, tb_iterator_ref_t result);
-
- // statement init
- tb_database_sql_statement_ref_t (*statement_init)(struct __tb_database_sql_impl_t* database, tb_char_t const* sql);
-
- // statement exit
- tb_void_t (*statement_exit)(struct __tb_database_sql_impl_t* database, tb_database_sql_statement_ref_t statement);
-
- // statement done
- tb_bool_t (*statement_done)(struct __tb_database_sql_impl_t* database, tb_database_sql_statement_ref_t statement);
-
- // statement bind
- tb_bool_t (*statement_bind)(struct __tb_database_sql_impl_t* database, tb_database_sql_statement_ref_t statement, tb_database_sql_value_t const* list, tb_size_t size);
-
-}tb_database_sql_impl_t;
-
-
-#endif
diff --git a/core/src/tbox/src/tbox/database/impl/sqlite3.c b/core/src/tbox/src/tbox/database/impl/sqlite3.c
deleted file mode 100644
index edbdf5a63..000000000
--- a/core/src/tbox/src/tbox/database/impl/sqlite3.c
+++ /dev/null
@@ -1,935 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file sqlite3.c
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "sqlite3"
-#define TB_TRACE_MODULE_DEBUG (1)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-#include <sqlite3.h>
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the sqlite3 result row type
-typedef struct __tb_database_sqlite3_result_row_t
-{
- // the iterator
- tb_iterator_t itor;
-
- // the row
- tb_size_t row;
-
- // the col count
- tb_size_t count;
-
- // the col value
- tb_database_sql_value_t value;
-
-}tb_database_sqlite3_result_row_t;
-
-// the sqlite3 result type
-typedef struct __tb_database_sqlite3_result_t
-{
- // the iterator
- tb_iterator_t itor;
-
- // the result
- tb_char_t** result;
-
- // the statement
- sqlite3_stmt* statement;
-
- // the row count
- tb_size_t count;
-
- // the row
- tb_database_sqlite3_result_row_t row;
-
-}tb_database_sqlite3_result_t;
-
-// the sqlite3 type
-typedef struct __tb_database_sqlite3_t
-{
- // the base
- tb_database_sql_impl_t base;
-
- // the database
- sqlite3* database;
-
- // the result
- tb_database_sqlite3_result_t result;
-
-}tb_database_sqlite3_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * library implementation
- */
-static tb_handle_t tb_database_sqlite3_library_init(tb_cpointer_t* ppriv)
-{
- // init it
- tb_int_t ok = SQLITE_OK;
- if ((ok = sqlite3_initialize()) != SQLITE_OK)
- {
- // trace
- tb_trace_e("init: sqlite3 library failed, error: %d", ok);
- return tb_null;
- }
-
- // ok
- return ppriv;
-}
-static tb_void_t tb_database_sqlite3_library_exit(tb_handle_t handle, tb_cpointer_t priv)
-{
- // exit it
- sqlite3_shutdown();
-}
-static tb_handle_t tb_database_sqlite3_library_load()
-{
- return tb_singleton_instance(TB_SINGLETON_TYPE_LIBRARY_SQLITE3, tb_database_sqlite3_library_init, tb_database_sqlite3_library_exit, tb_null, tb_null);
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * state implementation
- */
-static tb_size_t tb_database_sqlite3_state_from_errno(tb_size_t errno)
-{
- // done
- tb_size_t state = TB_STATE_DATABASE_UNKNOWN_ERROR;
- switch (errno)
- {
- case SQLITE_NOTADB:
- state = TB_STATE_DATABASE_NO_SUCH_DATABASE;
- break;
- case SQLITE_PERM:
- case SQLITE_AUTH:
- state = TB_STATE_DATABASE_ACCESS_DENIED;
- break;
- case SQLITE_ERROR:
- case SQLITE_INTERNAL:
- break;
- default:
- tb_trace_e("unknown errno: %lu", errno);
- break;
- }
-
- // ok?
- return state;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * iterator implementation
- */
-static tb_size_t tb_database_sqlite3_result_row_iterator_size(tb_iterator_ref_t iterator)
-{
- // check
- tb_database_sqlite3_result_t* result = (tb_database_sqlite3_result_t*)iterator;
- tb_assert(result);
-
- // size
- return result->count;
-}
-static tb_size_t tb_database_sqlite3_result_row_iterator_head(tb_iterator_ref_t iterator)
-{
- // head
- return 0;
-}
-static tb_size_t tb_database_sqlite3_result_row_iterator_tail(tb_iterator_ref_t iterator)
-{
- // check
- tb_database_sqlite3_result_t* result = (tb_database_sqlite3_result_t*)iterator;
- tb_assert(result);
-
- // tail
- return result->count;
-}
-static tb_size_t tb_database_sqlite3_result_row_iterator_prev(tb_iterator_ref_t iterator, tb_size_t itor)
-{
- // check
- tb_database_sqlite3_result_t* result = (tb_database_sqlite3_result_t*)iterator;
- tb_assert(result);
- tb_assert_and_check_return_val(itor && itor <= result->count, result->count);
-
- // cannot be the statement result
- tb_assert_and_check_return_val(!result->statement, result->count);
-
- // prev
- return itor - 1;
-}
-static tb_size_t tb_database_sqlite3_result_row_iterator_next(tb_iterator_ref_t iterator, tb_size_t itor)
-{
- // check
- tb_database_sqlite3_result_t* result = (tb_database_sqlite3_result_t*)iterator;
- tb_assert(result);
- tb_assert_and_check_return_val(itor < result->count, result->count);
-
- // statement result?
- if (result->statement)
- {
- // step statement
- tb_int_t ok = sqlite3_step(result->statement);
-
- // end?
- if (ok != SQLITE_ROW)
- {
- // reset it
- if (SQLITE_OK != sqlite3_reset(result->statement))
- {
- // the sqlite
- tb_database_sqlite3_t* sqlite = (tb_database_sqlite3_t*)iterator->priv;
- if (sqlite)
- {
- // save state
- sqlite->base.state = tb_database_sqlite3_state_from_errno(sqlite3_errcode(sqlite->database));
-
- // trace
- tb_trace_e("statement: reset failed, error[%d]: %s", sqlite3_errcode(sqlite->database), sqlite3_errmsg(sqlite->database));
- }
- }
-
- // tail
- return result->count;
- }
- }
-
- // next
- return itor + 1;
-}
-static tb_pointer_t tb_database_sqlite3_result_row_iterator_item(tb_iterator_ref_t iterator, tb_size_t itor)
-{
- // check
- tb_database_sqlite3_result_t* result = (tb_database_sqlite3_result_t*)iterator;
- tb_assert_and_check_return_val(result && (result->result || result->statement) && itor < result->count, tb_null);
-
- // save the row
- result->row.row = itor;
-
- // the row iterator
- return (tb_pointer_t)&result->row;
-}
-static tb_size_t tb_database_sqlite3_result_col_iterator_size(tb_iterator_ref_t iterator)
-{
- // check
- tb_database_sqlite3_result_row_t* row = (tb_database_sqlite3_result_row_t*)iterator;
- tb_assert_and_check_return_val(row, 0);
-
- // size
- return row->count;
-}
-static tb_size_t tb_database_sqlite3_result_col_iterator_head(tb_iterator_ref_t iterator)
-{
- // check
- tb_database_sqlite3_result_row_t* row = (tb_database_sqlite3_result_row_t*)iterator;
- tb_assert_and_check_return_val(row, 0);
-
- // head
- return 0;
-}
-static tb_size_t tb_database_sqlite3_result_col_iterator_tail(tb_iterator_ref_t iterator)
-{
- // check
- tb_database_sqlite3_result_row_t* row = (tb_database_sqlite3_result_row_t*)iterator;
- tb_assert_and_check_return_val(row, 0);
-
- // tail
- return row->count;
-}
-static tb_size_t tb_database_sqlite3_result_col_iterator_prev(tb_iterator_ref_t iterator, tb_size_t itor)
-{
- // check
- tb_database_sqlite3_result_row_t* row = (tb_database_sqlite3_result_row_t*)iterator;
- tb_assert_and_check_return_val(row && itor && itor <= row->count, 0);
-
- // prev
- return itor - 1;
-}
-static tb_size_t tb_database_sqlite3_result_col_iterator_next(tb_iterator_ref_t iterator, tb_size_t itor)
-{
- // check
- tb_database_sqlite3_result_row_t* row = (tb_database_sqlite3_result_row_t*)iterator;
- tb_assert_and_check_return_val(row && itor < row->count, row->count);
-
- // next
- return itor + 1;
-}
-static tb_pointer_t tb_database_sqlite3_result_col_iterator_item(tb_iterator_ref_t iterator, tb_size_t itor)
-{
- // check
- tb_database_sqlite3_result_row_t* row = (tb_database_sqlite3_result_row_t*)iterator;
- tb_assert_and_check_return_val(row && itor < row->count, tb_null);
-
- // the sqlite
- tb_database_sqlite3_t* sqlite = (tb_database_sqlite3_t*)iterator->priv;
- tb_assert_and_check_return_val(sqlite, tb_null);
-
- // result?
- if (sqlite->result.result)
- {
- // init value
- tb_database_sql_value_name_set(&row->value, (tb_char_t const*)sqlite->result.result[itor]);
- tb_database_sql_value_set_text(&row->value, (tb_char_t const*)sqlite->result.result[((1 + sqlite->result.row.row) * row->count) + itor], 0);
- return (tb_pointer_t)&row->value;
- }
- // statement result?
- else if (sqlite->result.statement)
- {
- // init name
- tb_database_sql_value_name_set(&row->value, sqlite3_column_name(sqlite->result.statement, itor));
-
- // init type
- tb_size_t type = sqlite3_column_type(sqlite->result.statement, itor);
- switch (type)
- {
- case SQLITE_INTEGER:
- tb_database_sql_value_set_int32(&row->value, sqlite3_column_int(sqlite->result.statement, itor));
- break;
- case SQLITE_TEXT:
- tb_database_sql_value_set_text(&row->value, (tb_char_t const*)sqlite3_column_text(sqlite->result.statement, itor), sqlite3_column_bytes(sqlite->result.statement, itor));
- break;
- case SQLITE_FLOAT:
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- tb_database_sql_value_set_double(&row->value, sqlite3_column_double(sqlite->result.statement, itor));
- break;
-#else
- // trace
- tb_trace1_e("float type is not supported, at col: %lu, please enable float config!", itor);
- return tb_null;
-#endif
- case SQLITE_BLOB:
- tb_database_sql_value_set_blob32(&row->value, (tb_byte_t const*)sqlite3_column_blob(sqlite->result.statement, itor), sqlite3_column_bytes(sqlite->result.statement, itor), tb_null);
- break;
- case SQLITE_NULL:
- tb_database_sql_value_set_null(&row->value);
- break;
- default:
- tb_trace_e("unknown field type: %s, at col: %lu", type, itor);
- return tb_null;
- }
-
- // ok
- return (tb_pointer_t)&row->value;
- }
-
- // failed
- tb_assert(0);
- return tb_null;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static __tb_inline__ tb_database_sqlite3_t* tb_database_sqlite3_cast(tb_database_sql_impl_t* database)
-{
- // check
- tb_assert_and_check_return_val(database && database->type == TB_DATABASE_SQL_TYPE_SQLITE3, tb_null);
-
- // cast
- return (tb_database_sqlite3_t*)database;
-}
-static tb_bool_t tb_database_sqlite3_open(tb_database_sql_impl_t* database)
-{
- // check
- tb_database_sqlite3_t* sqlite = tb_database_sqlite3_cast(database);
- tb_assert_and_check_return_val(sqlite, tb_false);
-
- // done
- tb_bool_t ok = tb_false;
- tb_char_t const* path = tb_null;
- do
- {
- // the database path
- path = tb_url_cstr(&database->url);
- tb_assert_and_check_break(path);
-
- // load sqlite3 library
- if (!tb_database_sqlite3_library_load()) break;
-
- // open database
- if (SQLITE_OK != sqlite3_open_v2(path, &sqlite->database, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, tb_null) || !sqlite->database)
- {
- // error
- if (sqlite->database)
- {
- // save state
- sqlite->base.state = tb_database_sqlite3_state_from_errno(sqlite3_errcode(sqlite->database));
-
- // trace
- tb_trace_e("open: %s failed, error[%d]: %s", path, sqlite3_errcode(sqlite->database), sqlite3_errmsg(sqlite->database));
- }
- break;
- }
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // trace
- tb_trace_d("open: %s: %s", path, ok? "ok" : "no");
-
- // ok?
- return ok;
-}
-static tb_void_t tb_database_sqlite3_clos(tb_database_sql_impl_t* database)
-{
- // check
- tb_database_sqlite3_t* sqlite = tb_database_sqlite3_cast(database);
- tb_assert_and_check_return(sqlite);
-
- // exit result first if exists
- if (sqlite->result.result) sqlite3_free_table(sqlite->result.result);
- sqlite->result.result = tb_null;
-
- // close database
- if (sqlite->database) sqlite3_close(sqlite->database);
- sqlite->database = tb_null;
-}
-static tb_void_t tb_database_sqlite3_exit(tb_database_sql_impl_t* database)
-{
- // check
- tb_database_sqlite3_t* sqlite = tb_database_sqlite3_cast(database);
- tb_assert_and_check_return(sqlite);
-
- // close it first
- tb_database_sqlite3_clos(database);
-
- // exit url
- tb_url_exit(&database->url);
-
- // exit it
- tb_free(sqlite);
-}
-static tb_bool_t tb_database_sqlite3_begin(tb_database_sql_impl_t* database)
-{
- // check
- tb_database_sqlite3_t* sqlite = tb_database_sqlite3_cast(database);
- tb_assert_and_check_return_val(sqlite && sqlite->database, tb_false);
-
- // done commit
- if (SQLITE_OK != sqlite3_exec(sqlite->database, "begin;", tb_null, tb_null, tb_null))
- {
- // save state
- sqlite->base.state = tb_database_sqlite3_state_from_errno(sqlite3_errcode(sqlite->database));
-
- // trace
- tb_trace_e("begin: failed, error[%d]: %s", sqlite3_errcode(sqlite->database), sqlite3_errmsg(sqlite->database));
- return tb_false;
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_database_sqlite3_commit(tb_database_sql_impl_t* database)
-{
- // check
- tb_database_sqlite3_t* sqlite = tb_database_sqlite3_cast(database);
- tb_assert_and_check_return_val(sqlite && sqlite->database, tb_false);
-
- // done commit
- if (SQLITE_OK != sqlite3_exec(sqlite->database, "commit;", tb_null, tb_null, tb_null))
- {
- // save state
- sqlite->base.state = tb_database_sqlite3_state_from_errno(sqlite3_errcode(sqlite->database));
-
- // trace
- tb_trace_e("commit: failed, error[%d]: %s", sqlite3_errcode(sqlite->database), sqlite3_errmsg(sqlite->database));
- return tb_false;
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_database_sqlite3_rollback(tb_database_sql_impl_t* database)
-{
- // check
- tb_database_sqlite3_t* sqlite = tb_database_sqlite3_cast(database);
- tb_assert_and_check_return_val(sqlite && sqlite->database, tb_false);
-
- // done rollback
- if (SQLITE_OK != sqlite3_exec(sqlite->database, "rollback;", tb_null, tb_null, tb_null))
- {
- // save state
- sqlite->base.state = tb_database_sqlite3_state_from_errno(sqlite3_errcode(sqlite->database));
-
- // trace
- tb_trace_e("rollback: failed, error[%d]: %s", sqlite3_errcode(sqlite->database), sqlite3_errmsg(sqlite->database));
- return tb_false;
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_database_sqlite3_done(tb_database_sql_impl_t* database, tb_char_t const* sql)
-{
- // check
- tb_database_sqlite3_t* sqlite = tb_database_sqlite3_cast(database);
- tb_assert_and_check_return_val(sqlite && sqlite->database && sql, tb_false);
-
- // done
- tb_bool_t ok = tb_false;
- do
- {
- // exit result first if exists
- if (sqlite->result.result) sqlite3_free_table(sqlite->result.result);
- sqlite->result.result = tb_null;
-
- // clear the lasr statement first
- sqlite->result.statement = tb_null;
-
- // clear the result row count first
- sqlite->result.count = 0;
-
- // clear the result col count first
- sqlite->result.row.count = 0;
-
- // done sql
- tb_int_t row_count = 0;
- tb_int_t col_count = 0;
- tb_char_t* error = tb_null;
- if (SQLITE_OK != sqlite3_get_table(sqlite->database, sql, &sqlite->result.result, &row_count, &col_count, &error))
- {
- // save state
- sqlite->base.state = tb_database_sqlite3_state_from_errno(sqlite3_errcode(sqlite->database));
-
- // trace
- tb_trace_e("done: sql: %s failed, error[%d]: %s", sql, sqlite3_errcode(sqlite->database), error);
-
- // exit error
- if (error) sqlite3_free(error);
- break;
- }
-
- // no result?
- if (!row_count)
- {
- // exit result
- if (sqlite->result.result) sqlite3_free_table(sqlite->result.result);
- sqlite->result.result = tb_null;
-
- // trace
- tb_trace_d("done: sql: %s: ok", sql);
-
- // ok
- ok = tb_true;
- break;
- }
-
- // save the result iterator mode
- sqlite->result.itor.mode = TB_ITERATOR_MODE_RACCESS | TB_ITERATOR_MODE_READONLY;
-
- // save result row count
- sqlite->result.count = row_count;
-
- // save result col count
- sqlite->result.row.count = col_count;
-
- // trace
- tb_trace_d("done: sql: %s: ok", sql);
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // ok?
- return ok;
-}
-static tb_void_t tb_database_sqlite3_result_exit(tb_database_sql_impl_t* database, tb_iterator_ref_t result)
-{
- // check
- tb_database_sqlite3_result_t* sqlite3_result = (tb_database_sqlite3_result_t*)result;
- tb_assert_and_check_return(sqlite3_result);
-
- // exit result
- if (sqlite3_result->result) sqlite3_free_table(sqlite3_result->result);
- sqlite3_result->result = tb_null;
-
- // clear the statement
- sqlite3_result->statement = tb_null;
-
- // clear result
- sqlite3_result->count = 0;
- sqlite3_result->row.count = 0;
-}
-static tb_iterator_ref_t tb_database_sqlite3_result_load(tb_database_sql_impl_t* database, tb_bool_t try_all)
-{
- // check
- tb_database_sqlite3_t* sqlite = tb_database_sqlite3_cast(database);
- tb_assert_and_check_return_val(sqlite && sqlite->database, tb_null);
-
- // ok?
- return (sqlite->result.result || sqlite->result.statement)? (tb_iterator_ref_t)&sqlite->result : tb_null;
-}
-static tb_void_t tb_database_sqlite3_statement_exit(tb_database_sql_impl_t* database, tb_database_sql_statement_ref_t statement)
-{
- // exit statement
- if (statement) sqlite3_finalize((sqlite3_stmt*)statement);
-}
-static tb_database_sql_statement_ref_t tb_database_sqlite3_statement_init(tb_database_sql_impl_t* database, tb_char_t const* sql)
-{
- // check
- tb_database_sqlite3_t* sqlite = tb_database_sqlite3_cast(database);
- tb_assert_and_check_return_val(sqlite && sqlite->database && sql, tb_null);
-
- // init statement
- sqlite3_stmt* statement = tb_null;
- if (SQLITE_OK != sqlite3_prepare_v2(sqlite->database, sql, -1, &statement, 0))
- {
- // save state
- sqlite->base.state = tb_database_sqlite3_state_from_errno(sqlite3_errcode(sqlite->database));
-
- // trace
- tb_trace_e("statement: init %s failed, error[%d]: %s", sql, sqlite3_errcode(sqlite->database), sqlite3_errmsg(sqlite->database));
- }
-
- // ok?
- return (tb_database_sql_statement_ref_t)statement;
-}
-static tb_bool_t tb_database_sqlite3_statement_done(tb_database_sql_impl_t* database, tb_database_sql_statement_ref_t statement)
-{
- // check
- tb_database_sqlite3_t* sqlite = tb_database_sqlite3_cast(database);
- tb_assert_and_check_return_val(sqlite && sqlite->database && statement, tb_false);
-
- // done
- tb_bool_t ok = tb_false;
- do
- {
- // exit result first if exists
- if (sqlite->result.result) sqlite3_free_table(sqlite->result.result);
- sqlite->result.result = tb_null;
-
- // clear the last statement first
- sqlite->result.statement = tb_null;
-
- // clear the result row count first
- sqlite->result.count = 0;
-
- // clear the result col count first
- sqlite->result.row.count = 0;
-
- // step statement
- tb_int_t result = sqlite3_step((sqlite3_stmt*)statement);
- tb_assert_and_check_break(result == SQLITE_DONE || result == SQLITE_ROW);
-
- // exists result?
- if (result == SQLITE_ROW)
- {
- // save the result iterator mode
- sqlite->result.itor.mode = TB_ITERATOR_MODE_FORWARD | TB_ITERATOR_MODE_READONLY;
-
- // save statement for iterating it
- sqlite->result.statement = (sqlite3_stmt*)statement;
-
- // save result row count
- sqlite->result.count = (tb_size_t)-1;
-
- // save result col count
- sqlite->result.row.count = sqlite3_column_count((sqlite3_stmt*)statement);
- }
- else
- {
- // reset it
- if (SQLITE_OK != sqlite3_reset((sqlite3_stmt*)statement))
- {
- // save state
- sqlite->base.state = tb_database_sqlite3_state_from_errno(sqlite3_errcode(sqlite->database));
-
- // trace
- tb_trace_e("statement: reset failed, error[%d]: %s", sqlite3_errcode(sqlite->database), sqlite3_errmsg(sqlite->database));
-
- // failed
- break;
- }
- }
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // ok?
- return ok;
-}
-static tb_void_t tb_database_sqlite3_statement_bind_exit(tb_pointer_t data)
-{
- // trace
- tb_trace_d("bind: exit: %p", data);
-
- // exit it
- if (data) tb_free(data);
-}
-static tb_bool_t tb_database_sqlite3_statement_bind(tb_database_sql_impl_t* database, tb_database_sql_statement_ref_t statement, tb_database_sql_value_t const* list, tb_size_t size)
-{
- // check
- tb_database_sqlite3_t* sqlite = tb_database_sqlite3_cast(database);
- tb_assert_and_check_return_val(sqlite && sqlite->database && statement && list && size, tb_false);
-
- // the param count
- tb_size_t param_count = (tb_size_t)sqlite3_bind_parameter_count((sqlite3_stmt*)statement);
- tb_assert_and_check_return_val(size == param_count, tb_false);
-
- // walk
- tb_size_t i = 0;
- for (i = 0; i < size; i++)
- {
- // the value
- tb_database_sql_value_t const* value = &list[i];
-
- // done
- tb_int_t ok = SQLITE_ERROR;
- tb_byte_t* data = tb_null;
- switch (value->type)
- {
- case TB_DATABASE_SQL_VALUE_TYPE_TEXT:
- tb_trace_i("sqlite3: test %lu %s", i, value->u.text.data);
- ok = sqlite3_bind_text((sqlite3_stmt*)statement, (tb_int_t)(i + 1), value->u.text.data, (tb_int_t)tb_database_sql_value_size(value), tb_null);
- break;
- case TB_DATABASE_SQL_VALUE_TYPE_INT64:
- case TB_DATABASE_SQL_VALUE_TYPE_UINT64:
- ok = sqlite3_bind_int64((sqlite3_stmt*)statement, (tb_int_t)(i + 1), tb_database_sql_value_int64(value));
- break;
- case TB_DATABASE_SQL_VALUE_TYPE_INT32:
- case TB_DATABASE_SQL_VALUE_TYPE_INT16:
- case TB_DATABASE_SQL_VALUE_TYPE_INT8:
- case TB_DATABASE_SQL_VALUE_TYPE_UINT32:
- case TB_DATABASE_SQL_VALUE_TYPE_UINT16:
- case TB_DATABASE_SQL_VALUE_TYPE_UINT8:
- ok = sqlite3_bind_int((sqlite3_stmt*)statement, (tb_int_t)(i + 1), (tb_int_t)tb_database_sql_value_int32(value));
- break;
- case TB_DATABASE_SQL_VALUE_TYPE_BLOB16:
- case TB_DATABASE_SQL_VALUE_TYPE_BLOB8:
- ok = sqlite3_bind_blob((sqlite3_stmt*)statement, (tb_int_t)(i + 1), value->u.blob.data, (tb_int_t)value->u.blob.size, tb_null);
- break;
- case TB_DATABASE_SQL_VALUE_TYPE_BLOB32:
- {
- if (value->u.blob.stream)
- {
- // done
- do
- {
- // the stream size
- tb_hong_t size = tb_stream_size(value->u.blob.stream);
- tb_assert_and_check_break(size >= 0);
-
- // make data
- data = tb_malloc0_bytes((tb_size_t)size);
- tb_assert_and_check_break(data);
-
- // read data
- if (!tb_stream_bread(value->u.blob.stream, data, (tb_size_t)size)) break;
-
- // bind it
- ok = sqlite3_bind_blob((sqlite3_stmt*)statement, (tb_int_t)(i + 1), data, (tb_int_t)size, tb_database_sqlite3_statement_bind_exit);
-
- } while (0);
- }
- else ok = sqlite3_bind_blob((sqlite3_stmt*)statement, (tb_int_t)(i + 1), value->u.blob.data, (tb_int_t)value->u.blob.size, tb_null);
- }
- break;
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- case TB_DATABASE_SQL_VALUE_TYPE_FLOAT:
- case TB_DATABASE_SQL_VALUE_TYPE_DOUBLE:
- ok = sqlite3_bind_double((sqlite3_stmt*)statement, (tb_int_t)(i + 1), (tb_double_t)tb_database_sql_value_double(value));
- break;
-#endif
- case TB_DATABASE_SQL_VALUE_TYPE_NULL:
- ok = sqlite3_bind_null((sqlite3_stmt*)statement, (tb_int_t)(i + 1));
- break;
- default:
- tb_trace_e("statement: bind: unknown value type: %lu", value->type);
- break;
- }
-
- // failed?
- if (SQLITE_OK != ok)
- {
- // exit data
- if (data) tb_free(data);
- data = tb_null;
-
- // save state
- sqlite->base.state = tb_database_sqlite3_state_from_errno(sqlite3_errcode(sqlite->database));
-
- // trace
- tb_trace_e("statement: bind value[%lu] failed, error[%d]: %s", i, sqlite3_errcode(sqlite->database), sqlite3_errmsg(sqlite->database));
- break;
- }
- }
-
- // ok?
- return (i == size)? tb_true : tb_false;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-tb_size_t tb_database_sqlite3_probe(tb_url_ref_t url)
-{
- // check
- tb_assert_and_check_return_val(url, 0);
-
- // done
- tb_size_t score = 0;
- tb_stream_ref_t stream = tb_null;
- do
- {
- // the url arguments
- tb_char_t const* args = tb_url_args(url);
- if (args)
- {
- // find the database type
- tb_char_t const* ptype = tb_stristr(args, "type=");
- if (ptype && !tb_strnicmp(ptype + 5, "sqlite3", 7))
- {
- // ok
- score = 100;
- break;
- }
- }
-
- // has host or port? no sqlite3
- if (tb_url_host(url) || tb_url_port(url)) break;
-
- // the database path
- tb_char_t const* path = tb_url_cstr((tb_url_ref_t)url);
- tb_assert_and_check_break(path);
-
- // is file?
- if (tb_url_protocol(url) == TB_URL_PROTOCOL_FILE) score += 20;
-
- // init stream
- stream = tb_stream_init_from_url(path);
- tb_assert_and_check_break(stream);
-
- // open stream
- if (!tb_stream_open(stream)) break;
-
- // read head
- tb_char_t head[16] = {0};
- if (!tb_stream_bread(stream, (tb_byte_t*)head, 15)) break;
-
- // is sqlite3?
- if (!tb_stricmp(head, "SQLite format 3")) score = 100;
-
- } while (0);
-
- // exit stream
- if (stream) tb_stream_exit(stream);
- stream = tb_null;
-
- // trace
- tb_trace_d("probe: %s, score: %lu", tb_url_cstr((tb_url_ref_t)url), score);
-
- // ok?
- return score;
-}
-tb_database_sql_ref_t tb_database_sqlite3_init(tb_url_ref_t url)
-{
- // check
- tb_assert_and_check_return_val(url, tb_null);
-
- // done
- tb_bool_t ok = tb_false;
- tb_database_sqlite3_t* sqlite = tb_null;
- do
- {
- // make database
- sqlite = tb_malloc0_type(tb_database_sqlite3_t);
- tb_assert_and_check_break(sqlite);
-
- // init database
- sqlite->base.type = TB_DATABASE_SQL_TYPE_SQLITE3;
- sqlite->base.open = tb_database_sqlite3_open;
- sqlite->base.clos = tb_database_sqlite3_clos;
- sqlite->base.exit = tb_database_sqlite3_exit;
- sqlite->base.done = tb_database_sqlite3_done;
- sqlite->base.begin = tb_database_sqlite3_begin;
- sqlite->base.commit = tb_database_sqlite3_commit;
- sqlite->base.rollback = tb_database_sqlite3_rollback;
- sqlite->base.result_load = tb_database_sqlite3_result_load;
- sqlite->base.result_exit = tb_database_sqlite3_result_exit;
- sqlite->base.statement_init = tb_database_sqlite3_statement_init;
- sqlite->base.statement_exit = tb_database_sqlite3_statement_exit;
- sqlite->base.statement_done = tb_database_sqlite3_statement_done;
- sqlite->base.statement_bind = tb_database_sqlite3_statement_bind;
-
- // init result row iterator
- sqlite->result.itor.mode = 0;
- sqlite->result.itor.priv = (tb_pointer_t)sqlite;
- sqlite->result.itor.step = 0;
- sqlite->result.itor.size = tb_database_sqlite3_result_row_iterator_size;
- sqlite->result.itor.head = tb_database_sqlite3_result_row_iterator_head;
- sqlite->result.itor.tail = tb_database_sqlite3_result_row_iterator_tail;
- sqlite->result.itor.prev = tb_database_sqlite3_result_row_iterator_prev;
- sqlite->result.itor.next = tb_database_sqlite3_result_row_iterator_next;
- sqlite->result.itor.item = tb_database_sqlite3_result_row_iterator_item;
- sqlite->result.itor.copy = tb_null;
- sqlite->result.itor.comp = tb_null;
-
- // init result col iterator
- sqlite->result.row.itor.mode = TB_ITERATOR_MODE_RACCESS | TB_ITERATOR_MODE_READONLY;
- sqlite->result.row.itor.priv = (tb_pointer_t)sqlite;
- sqlite->result.row.itor.step = 0;
- sqlite->result.row.itor.size = tb_database_sqlite3_result_col_iterator_size;
- sqlite->result.row.itor.head = tb_database_sqlite3_result_col_iterator_head;
- sqlite->result.row.itor.tail = tb_database_sqlite3_result_col_iterator_tail;
- sqlite->result.row.itor.prev = tb_database_sqlite3_result_col_iterator_prev;
- sqlite->result.row.itor.next = tb_database_sqlite3_result_col_iterator_next;
- sqlite->result.row.itor.item = tb_database_sqlite3_result_col_iterator_item;
- sqlite->result.row.itor.copy = tb_null;
- sqlite->result.row.itor.comp = tb_null;
-
- // init url
- if (!tb_url_init(&sqlite->base.url)) break;
-
- // copy url
- tb_url_copy(&sqlite->base.url, url);
-
- // init state
- sqlite->base.state = TB_STATE_OK;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit database
- if (sqlite) tb_database_sqlite3_exit((tb_database_sql_impl_t*)sqlite);
- sqlite = tb_null;
- }
-
- // ok?
- return (tb_database_sql_ref_t)sqlite;
-}
-
diff --git a/core/src/tbox/src/tbox/database/impl/sqlite3.h b/core/src/tbox/src/tbox/database/impl/sqlite3.h
deleted file mode 100644
index 871f5d9ef..000000000
--- a/core/src/tbox/src/tbox/database/impl/sqlite3.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file sqlite3.h
- */
-#ifndef TB_DATABASE_IMPL_SQLITE3_H
-#define TB_DATABASE_IMPL_SQLITE3_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/* probe sqlite3 from the url
- *
- * @param url the database url
- *
- * @return the score
- */
-tb_size_t tb_database_sqlite3_probe(tb_url_ref_t url);
-
-/* init sqlite3
- *
- * @param url the database url
- *
- * @return the database handle
- */
-tb_database_sql_ref_t tb_database_sqlite3_init(tb_url_ref_t url);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/database/prefix.h b/core/src/tbox/src/tbox/database/prefix.h
deleted file mode 100644
index 6bc82299d..000000000
--- a/core/src/tbox/src/tbox/database/prefix.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file prefix.h
- * @ingroup database
- *
- */
-#ifndef TB_DATABASE_PREFIX_H
-#define TB_DATABASE_PREFIX_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "../prefix.h"
-#include "../libc/libc.h"
-#include "../network/url.h"
-#include "../container/iterator.h"
-
-
-#endif
diff --git a/core/src/tbox/src/tbox/database/sql.c b/core/src/tbox/src/tbox/database/sql.c
deleted file mode 100644
index c866c0ace..000000000
--- a/core/src/tbox/src/tbox/database/sql.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file sql.c
- * @defgroup database
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "database"
-#define TB_TRACE_MODULE_DEBUG (1)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "sql.h"
-#include "impl/prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_database_sql_ref_t tb_database_sql_init(tb_char_t const* url)
-{
- // check
- tb_assert_and_check_return_val(url, tb_null);
-
- // done
- tb_bool_t ok = tb_false;
- tb_database_sql_ref_t database = tb_null;
- tb_url_t database_url;
- do
- {
- // trace
- tb_trace_d("init: %s: ..", url);
-
- // init url
- if (!tb_url_init(&database_url)) break;
-
- // make url
- if (!tb_url_cstr_set(&database_url, url)) break;
-
- // check protocol
- tb_size_t protocol = tb_url_protocol(&database_url);
- tb_assert_and_check_break(protocol == TB_URL_PROTOCOL_SQL || protocol == TB_URL_PROTOCOL_FILE);
-
- // the probe func
- static tb_size_t (*s_probe[])(tb_url_ref_t) =
- {
- tb_null
-#ifdef TB_CONFIG_PACKAGE_HAVE_MYSQL
- , tb_database_mysql_probe
-#endif
-#ifdef TB_CONFIG_PACKAGE_HAVE_SQLITE3
- , tb_database_sqlite3_probe
-#endif
- };
-
- // the init func
- static tb_database_sql_ref_t (*s_init[])(tb_url_ref_t) =
- {
- tb_null
-#ifdef TB_CONFIG_PACKAGE_HAVE_MYSQL
- , tb_database_mysql_init
-#endif
-#ifdef TB_CONFIG_PACKAGE_HAVE_SQLITE3
- , tb_database_sqlite3_init
-#endif
- };
-
- // probe the database type
- tb_size_t i = 1;
- tb_size_t n = tb_arrayn(s_probe);
- tb_size_t s = 0;
- tb_size_t m = 0;
- for (; i < n; i++)
- {
- if (s_probe[i])
- {
- // probe it
- tb_size_t score = s_probe[i](&database_url);
- if (score > s)
- {
- // save the max score
- s = score;
- m = i;
-
- // ok?
- if (score == 100) break;
- }
- }
- }
- tb_check_break(m < n && s_init[m]);
-
- // init it
- database = s_init[m](&database_url);
- tb_assert_and_check_break(database);
-
- // trace
- tb_trace_d("init: %s: ok", url);
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // exit url
- tb_url_exit(&database_url);
-
- // failed?
- if (!ok)
- {
- // trace
- tb_trace_d("init: %s: no", url);
-
- // exit database
- if (database) tb_database_sql_exit(database);
- database = tb_null;
- }
-
- // ok?
- return database;
-}
-tb_void_t tb_database_sql_exit(tb_database_sql_ref_t database)
-{
- // check
- tb_database_sql_impl_t* impl = (tb_database_sql_impl_t*)database;
- tb_assert_and_check_return(impl);
-
- // trace
- tb_trace_d("exit: ..");
-
- // exit it
- if (impl->exit) impl->exit(impl);
-
- // trace
- tb_trace_d("exit: ok");
-}
-tb_size_t tb_database_sql_type(tb_database_sql_ref_t database)
-{
- // check
- tb_database_sql_impl_t* impl = (tb_database_sql_impl_t*)database;
- tb_assert_and_check_return_val(impl, TB_DATABASE_SQL_TYPE_NONE);
-
- // the database type
- return impl->type;
-}
-tb_bool_t tb_database_sql_open(tb_database_sql_ref_t database)
-{
- // check
- tb_database_sql_impl_t* impl = (tb_database_sql_impl_t*)database;
- tb_assert_and_check_return_val(impl && impl->open, tb_false);
-
- // opened?
- tb_check_return_val(!impl->bopened, tb_true);
-
- // init state
- impl->state = TB_STATE_DATABASE_UNKNOWN_ERROR;
-
- // open it
- impl->bopened = impl->open(impl);
-
- // save state
- if (impl->bopened) impl->state = TB_STATE_OK;
-
- // ok?
- return impl->bopened;
-}
-tb_void_t tb_database_sql_clos(tb_database_sql_ref_t database)
-{
- // check
- tb_database_sql_impl_t* impl = (tb_database_sql_impl_t*)database;
- tb_assert_and_check_return(impl);
-
- // opened?
- tb_check_return(impl->bopened);
-
- // clos it
- if (impl->clos) impl->clos(impl);
-
- // closed
- impl->bopened = tb_false;
-
- // clear state
- impl->state = TB_STATE_OK;
-}
-tb_size_t tb_database_sql_state(tb_database_sql_ref_t database)
-{
- // check
- tb_database_sql_impl_t* impl = (tb_database_sql_impl_t*)database;
- tb_assert_and_check_return_val(impl, TB_STATE_UNKNOWN_ERROR);
-
- // the state
- return impl->state;
-}
-tb_bool_t tb_database_sql_begin(tb_database_sql_ref_t database)
-{
- // check
- tb_database_sql_impl_t* impl = (tb_database_sql_impl_t*)database;
- tb_assert_and_check_return_val(impl && impl->commit, tb_false);
-
- // init state
- impl->state = TB_STATE_DATABASE_UNKNOWN_ERROR;
-
- // opened?
- tb_assert_and_check_return_val(impl->bopened, tb_false);
-
- // begin it
- tb_bool_t ok = impl->begin(impl);
-
- // save state
- if (ok) impl->state = TB_STATE_OK;
-
- // ok?
- return ok;
-}
-tb_bool_t tb_database_sql_commit(tb_database_sql_ref_t database)
-{
- // check
- tb_database_sql_impl_t* impl = (tb_database_sql_impl_t*)database;
- tb_assert_and_check_return_val(impl && impl->commit, tb_false);
-
- // init state
- impl->state = TB_STATE_DATABASE_UNKNOWN_ERROR;
-
- // opened?
- tb_assert_and_check_return_val(impl->bopened, tb_false);
-
- // commit it
- tb_bool_t ok = impl->commit(impl);
-
- // save state
- if (ok) impl->state = TB_STATE_OK;
-
- // ok?
- return ok;
-}
-tb_bool_t tb_database_sql_rollback(tb_database_sql_ref_t database)
-{
- // check
- tb_database_sql_impl_t* impl = (tb_database_sql_impl_t*)database;
- tb_assert_and_check_return_val(impl && impl->rollback, tb_false);
-
- // init state
- impl->state = TB_STATE_DATABASE_UNKNOWN_ERROR;
-
- // opened?
- tb_assert_and_check_return_val(impl->bopened, tb_false);
-
- // rollback it
- tb_bool_t ok = impl->rollback(impl);
-
- // save state
- if (ok) impl->state = TB_STATE_OK;
-
- // ok?
- return ok;
-}
-tb_bool_t tb_database_sql_done(tb_database_sql_ref_t database, tb_char_t const* sql)
-{
- // check
- tb_database_sql_impl_t* impl = (tb_database_sql_impl_t*)database;
- tb_assert_and_check_return_val(impl && impl->done && sql, tb_false);
-
- // init state
- impl->state = TB_STATE_DATABASE_UNKNOWN_ERROR;
-
- // opened?
- tb_assert_and_check_return_val(impl->bopened, tb_false);
-
- // done it
- tb_bool_t ok = impl->done(impl, sql);
-
- // trace
- tb_trace_d("done: sql: %s: %s", sql, ok? "ok" : "no");
-
- // save state
- if (ok) impl->state = TB_STATE_OK;
-
- // ok?
- return ok;
-}
-tb_iterator_ref_t tb_database_sql_result_load(tb_database_sql_ref_t database, tb_bool_t ball)
-{
- // check
- tb_database_sql_impl_t* impl = (tb_database_sql_impl_t*)database;
- tb_assert_and_check_return_val(impl && impl->result_load, tb_null);
-
- // init state
- impl->state = TB_STATE_DATABASE_UNKNOWN_ERROR;
-
- // opened?
- tb_assert_and_check_return_val(impl->bopened, tb_null);
-
- // load it
- tb_iterator_ref_t result = impl->result_load(impl, ball);
-
- // save state
- if (result) impl->state = TB_STATE_OK;
-
- // ok?
- return result;
-}
-tb_void_t tb_database_sql_result_exit(tb_database_sql_ref_t database, tb_iterator_ref_t result)
-{
- // check
- tb_database_sql_impl_t* impl = (tb_database_sql_impl_t*)database;
- tb_assert_and_check_return(impl && impl->result_exit && result);
-
- // opened?
- tb_assert_and_check_return(impl->bopened);
-
- // exit it
- impl->result_exit(impl, result);
-
- // clear state
- impl->state = TB_STATE_OK;
-}
-tb_database_sql_statement_ref_t tb_database_sql_statement_init(tb_database_sql_ref_t database, tb_char_t const* sql)
-{
- // check
- tb_database_sql_impl_t* impl = (tb_database_sql_impl_t*)database;
- tb_assert_and_check_return_val(impl && impl->statement_init && sql, tb_null);
-
- // init state
- impl->state = TB_STATE_DATABASE_UNKNOWN_ERROR;
-
- // opened?
- tb_assert_and_check_return_val(impl->bopened, tb_null);
-
- // init statement
- tb_database_sql_statement_ref_t statement = impl->statement_init(impl, sql);
-
- // save state
- if (statement) impl->state = TB_STATE_OK;
-
- // ok?
- return statement;
-}
-tb_void_t tb_database_sql_statement_exit(tb_database_sql_ref_t database, tb_database_sql_statement_ref_t statement)
-{
- // check
- tb_database_sql_impl_t* impl = (tb_database_sql_impl_t*)database;
- tb_assert_and_check_return(impl && impl->statement_done && statement);
-
- // opened?
- tb_assert_and_check_return(impl->bopened);
-
- // exit statement
- impl->statement_exit(impl, statement);
-
- // clear state
- impl->state = TB_STATE_OK;
-}
-tb_bool_t tb_database_sql_statement_done(tb_database_sql_ref_t database, tb_database_sql_statement_ref_t statement)
-{
- // check
- tb_database_sql_impl_t* impl = (tb_database_sql_impl_t*)database;
- tb_assert_and_check_return_val(impl && impl->statement_done && statement, tb_false);
-
- // init state
- impl->state = TB_STATE_DATABASE_UNKNOWN_ERROR;
-
- // opened?
- tb_assert_and_check_return_val(impl->bopened, tb_false);
-
- // done statement
- tb_bool_t ok = impl->statement_done(impl, statement);
-
- // save state
- if (ok) impl->state = TB_STATE_OK;
-
- // ok?
- return ok;
-}
-tb_bool_t tb_database_sql_statement_bind(tb_database_sql_ref_t database, tb_database_sql_statement_ref_t statement, tb_database_sql_value_t const* list, tb_size_t size)
-{
- // check
- tb_database_sql_impl_t* impl = (tb_database_sql_impl_t*)database;
- tb_assert_and_check_return_val(impl && impl->statement_bind && statement && list && size, tb_false);
-
- // init state
- impl->state = TB_STATE_DATABASE_UNKNOWN_ERROR;
-
- // opened?
- tb_assert_and_check_return_val(impl->bopened, tb_false);
-
- // bind statement argument
- tb_bool_t ok = impl->statement_bind(impl, statement, list, size);
-
- // save state
- if (ok) impl->state = TB_STATE_OK;
-
- // ok?
- return ok;
-}
diff --git a/core/src/tbox/src/tbox/database/sql.h b/core/src/tbox/src/tbox/database/sql.h
deleted file mode 100644
index 62e06facd..000000000
--- a/core/src/tbox/src/tbox/database/sql.h
+++ /dev/null
@@ -1,339 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file sql.h
- * @ingroup database
- */
-#ifndef TB_DATABASE_SQL_H
-#define TB_DATABASE_SQL_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-#include "value.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the sql database type enum
-typedef enum __tb_database_sql_type_e
-{
- TB_DATABASE_SQL_TYPE_NONE = 0
-, TB_DATABASE_SQL_TYPE_MYSQL = 1
-, TB_DATABASE_SQL_TYPE_SQLITE3 = 2
-
-}tb_database_sql_type_e;
-
-/// the database sql ref type
-typedef __tb_typeref__(database_sql);
-
-/// the database sql statement ref type
-typedef __tb_typeref__(database_sql_statement);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init sql database
- *
- * @param url the database url
- * "sql://localhost/?type=mysql&username=xxxx&password=xxxx"
- * "sql://localhost:3306/?type=mysql&username=xxxx&password=xxxx&database=xxxx"
- * "sql:///home/file.sqlitedb?type=sqlite3"
- * "/home/file.sqlite3"
- * "file:///home/file.sqlitedb"
- * "C://home/file.sqlite3"
- *
- * @return the database
- */
-tb_database_sql_ref_t tb_database_sql_init(tb_char_t const* url);
-
-/*! exit database
- *
- * @param database the database handle
- */
-tb_void_t tb_database_sql_exit(tb_database_sql_ref_t database);
-
-/*! the database type
- *
- * @param database the database handle
- *
- * @return the database type
- */
-tb_size_t tb_database_sql_type(tb_database_sql_ref_t database);
-
-/*! open database
- *
- * @code
- tb_database_sql_ref_t database = tb_database_sql_init("sql://localhost/?type=mysql&username=xxxx&password=xxxx");
- if (database)
- {
- // open it
- if (tb_database_sql_open(database))
- {
- // done it
- // ...
-
- // close it
- tb_database_sql_clos(database);
- }
- tb_database_sql_exit(database);
- }
- * @endcode
- *
- * @param database the database handle
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_database_sql_open(tb_database_sql_ref_t database);
-
-/*! clos database
- *
- * @param database the database handle
- */
-tb_void_t tb_database_sql_clos(tb_database_sql_ref_t database);
-
-/*! begin transaction
- *
- * @param database the database handle
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_database_sql_begin(tb_database_sql_ref_t database);
-
-/*! commit transaction
- *
- * @param database the database handle
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_database_sql_commit(tb_database_sql_ref_t database);
-
-/*! rollback transaction
- *
- * @param database the database handle
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_database_sql_rollback(tb_database_sql_ref_t database);
-
-/*! the database state
- *
- * @param database the database handle
- *
- * @return the database state
- */
-tb_size_t tb_database_sql_state(tb_database_sql_ref_t database);
-
-/*! done database
- *
- * @code
- *
- * // done sql
- * if (!tb_database_sql_done(database, "select * from table"))
- * {
- * // trace
- * tb_trace_e("done sql failed, error: %s", tb_state_cstr(tb_database_sql_state(database)));
- * return ;
- * }
- *
- * // load result
- * // ..
- *
- * @endcode
- *
- * @param database the database handle
- * @param sql the sql command
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_database_sql_done(tb_database_sql_ref_t database, tb_char_t const* sql);
-
-/*! load the database result
- *
- * @code
- *
- // done sql
- // ..
-
- // load result
- tb_iterator_ref_t result = tb_database_sql_result_load(database, tb_true);
- if (result)
- {
- // walk result
- tb_for_all_if (tb_iterator_ref_t, row, result, row)
- {
- // walk values
- tb_for_all_if (tb_database_sql_value_t*, value, row, value)
- {
- tb_trace_i("name: %s, data: %s, at: %lux%lu", tb_database_sql_value_name(value), tb_database_sql_value_text(value), row_itor, item_itor);
- }
- }
-
- // exit result
- tb_database_sql_result_exit(result);
- }
-
- // load result
- tb_iterator_ref_t result = tb_database_sql_result_load(database, tb_false);
- if (result)
- {
- // walk result
- tb_for_all_if (tb_iterator_ref_t, row, result, row)
- {
- // field count
- tb_trace_i("count: %lu", tb_iterator_size(row));
-
- // id
- tb_database_sql_value_t const* id = tb_iterator_item(row, 0);
- if (id)
- {
- tb_trace_i("id: %d", tb_database_sql_value_int32(id));
- }
-
- // name
- tb_database_sql_value_t const* name = tb_iterator_item(row, 1);
- if (name)
- {
- tb_trace_i("name: %s", tb_database_sql_value_text(name));
- }
-
- // blob
- tb_database_sql_value_t const* blob = tb_iterator_item(row, 2);
- if (blob)
- {
- // data?
- tb_stream_ref_t stream = tb_null;
- if (tb_database_sql_value_blob(blob))
- {
- // trace
- tb_trace_i("[data: %p, size: %lu] ", tb_database_sql_value_blob(blob), tb_database_sql_value_size(blob));
- }
- // stream?
- else if ((stream = tb_database_sql_value_blob_stream(blob)))
- {
- // trace
- tb_trace_i("[stream: %p, size: %lld] ", stream, tb_stream_size(stream));
-
- // read stream
- // ...
- }
- // null?
- else
- {
- // trace
- tb_trace_i("[%s:null] ", tb_database_sql_value_name(blob));
- }
- }
-
- }
-
- // exit result
- tb_database_sql_result_exit(result);
- }
-
- * @endcode
- *
- * @param database the database handle
- * @param try_all try loading all result into memory
- *
- * @return the database result
- */
-tb_iterator_ref_t tb_database_sql_result_load(tb_database_sql_ref_t database, tb_bool_t try_all);
-
-/*! exit the database result
- *
- * @param database the database handle
- * @param result the database result
- */
-tb_void_t tb_database_sql_result_exit(tb_database_sql_ref_t database, tb_iterator_ref_t result);
-
-/*! init the database statement
- *
- * @param database the database handle
- * @param sql the sql command
- *
- * @return the statement handle
- */
-tb_database_sql_statement_ref_t tb_database_sql_statement_init(tb_database_sql_ref_t database, tb_char_t const* sql);
-
-/*! exit the database statement
- *
- * @param database the database handle
- * @param statement the statement handle
- */
-tb_void_t tb_database_sql_statement_exit(tb_database_sql_ref_t database, tb_database_sql_statement_ref_t statement);
-
-/*! done the database statement
- *
- * @code
- tb_database_sql_statement_ref_t statement = tb_database_sql_statement_init(database, "select * from table where id=?");
- if (statement)
- {
- // bind arguments
- tb_database_sql_value_t list[1] = {0};
- tb_database_sql_value_set_int32(&list[0], 12345);
- if (tb_database_sql_statement_bind(database, statement, list, tb_arrayn(list)))
- {
- // done statement
- if (tb_database_sql_statement_done(database, statement))
- {
- // load result
- // ...
- }
- }
-
- // exit statement
- tb_database_sql_statement_exit(database, statement);
- }
- * @endcode
- *
- * @param database the database handle
- * @param statement the statement handle
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_database_sql_statement_done(tb_database_sql_ref_t database, tb_database_sql_statement_ref_t statement);
-
-/*! bind the database statement argument
- *
- * @param database the database handle
- * @param statement the statement handle
- * @param list the argument value list
- * @param size the argument value count
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_database_sql_statement_bind(tb_database_sql_ref_t database, tb_database_sql_statement_ref_t statement, tb_database_sql_value_t const* list, tb_size_t size);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/database/value.c b/core/src/tbox/src/tbox/database/value.c
deleted file mode 100644
index 5909a0588..000000000
--- a/core/src/tbox/src/tbox/database/value.c
+++ /dev/null
@@ -1,496 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file value.c
- * @ingroup database
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "value"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "value.h"
-#include "../stream/stream.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_size_t tb_database_sql_value_size(tb_database_sql_value_t const* value)
-{
- // check
- tb_assert_and_check_return_val(value, 0);
-
- // done
- switch (value->type)
- {
- case TB_DATABASE_SQL_VALUE_TYPE_TEXT:
- if (!value->u.text.hint && value->u.text.data)
- {
- ((tb_database_sql_value_t*)value)->u.text.hint = tb_strlen(value->u.text.data);
- }
- return value->u.text.hint;
- case TB_DATABASE_SQL_VALUE_TYPE_BLOB32:
- case TB_DATABASE_SQL_VALUE_TYPE_BLOB16:
- case TB_DATABASE_SQL_VALUE_TYPE_BLOB8:
- return value->u.blob.size;
- case TB_DATABASE_SQL_VALUE_TYPE_INT32:
- case TB_DATABASE_SQL_VALUE_TYPE_UINT32:
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- case TB_DATABASE_SQL_VALUE_TYPE_FLOAT:
-#endif
- return 4;
- case TB_DATABASE_SQL_VALUE_TYPE_INT64:
- case TB_DATABASE_SQL_VALUE_TYPE_UINT64:
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- case TB_DATABASE_SQL_VALUE_TYPE_DOUBLE:
-#endif
- return 8;
- case TB_DATABASE_SQL_VALUE_TYPE_INT16:
- case TB_DATABASE_SQL_VALUE_TYPE_UINT16:
- return 2;
- case TB_DATABASE_SQL_VALUE_TYPE_INT8:
- case TB_DATABASE_SQL_VALUE_TYPE_UINT8:
- return 1;
- default:
- tb_trace_e("unknown type: %lu", value->type);
- break;
- }
-
- return 0;
-}
-tb_int8_t tb_database_sql_value_int8(tb_database_sql_value_t const* value)
-{
- return (tb_int8_t)tb_database_sql_value_int32(value);
-}
-tb_int16_t tb_database_sql_value_int16(tb_database_sql_value_t const* value)
-{
- return (tb_int16_t)tb_database_sql_value_int32(value);
-}
-tb_int32_t tb_database_sql_value_int32(tb_database_sql_value_t const* value)
-{
- // check
- tb_assert_and_check_return_val(value, 0);
-
- // done
- switch (value->type)
- {
- case TB_DATABASE_SQL_VALUE_TYPE_INT32:
- return (tb_int32_t)value->u.i32;
- case TB_DATABASE_SQL_VALUE_TYPE_INT64:
- return (tb_int32_t)value->u.i64;
- case TB_DATABASE_SQL_VALUE_TYPE_INT16:
- return (tb_int32_t)value->u.i16;
- case TB_DATABASE_SQL_VALUE_TYPE_INT8:
- return (tb_int32_t)value->u.i8;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT32:
- return (tb_int32_t)value->u.u32;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT64:
- return (tb_int32_t)value->u.u64;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT16:
- return (tb_int32_t)value->u.u16;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT8:
- return (tb_int32_t)value->u.u8;
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- case TB_DATABASE_SQL_VALUE_TYPE_FLOAT:
- return (tb_int32_t)value->u.f;
- case TB_DATABASE_SQL_VALUE_TYPE_DOUBLE:
- return (tb_int32_t)value->u.d;
-#endif
- case TB_DATABASE_SQL_VALUE_TYPE_TEXT:
- return value->u.text.data? (tb_int32_t)tb_stoi32(value->u.text.data) : 0;
- default:
- tb_trace_e("unknown number type: %lu", value->type);
- break;
- }
-
- return 0;
-}
-tb_int64_t tb_database_sql_value_int64(tb_database_sql_value_t const* value)
-{
- // check
- tb_assert_and_check_return_val(value, 0);
-
- // done
- switch (value->type)
- {
- case TB_DATABASE_SQL_VALUE_TYPE_INT64:
- return (tb_int64_t)value->u.i64;
- case TB_DATABASE_SQL_VALUE_TYPE_INT32:
- return (tb_int64_t)value->u.i32;
- case TB_DATABASE_SQL_VALUE_TYPE_INT16:
- return (tb_int64_t)value->u.i16;
- case TB_DATABASE_SQL_VALUE_TYPE_INT8:
- return (tb_int64_t)value->u.i8;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT64:
- return (tb_int64_t)value->u.u64;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT32:
- return (tb_int64_t)value->u.u32;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT16:
- return (tb_int64_t)value->u.u16;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT8:
- return (tb_int64_t)value->u.u8;
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- case TB_DATABASE_SQL_VALUE_TYPE_FLOAT:
- return (tb_int64_t)value->u.f;
- case TB_DATABASE_SQL_VALUE_TYPE_DOUBLE:
- return (tb_int64_t)value->u.d;
-#endif
- case TB_DATABASE_SQL_VALUE_TYPE_TEXT:
- return value->u.text.data? (tb_int64_t)tb_stoi64(value->u.text.data) : 0;
- default:
- tb_trace_e("unknown number type: %lu", value->type);
- break;
- }
-
- return 0;
-}
-tb_uint8_t tb_database_sql_value_uint8(tb_database_sql_value_t const* value)
-{
- return (tb_uint8_t)tb_database_sql_value_uint32(value);
-}
-tb_uint16_t tb_database_sql_value_uint16(tb_database_sql_value_t const* value)
-{
- return (tb_uint16_t)tb_database_sql_value_uint32(value);
-}
-tb_uint32_t tb_database_sql_value_uint32(tb_database_sql_value_t const* value)
-{
- // check
- tb_assert_and_check_return_val(value, 0);
-
- // done
- switch (value->type)
- {
- case TB_DATABASE_SQL_VALUE_TYPE_UINT32:
- return (tb_uint32_t)value->u.u32;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT64:
- return (tb_uint32_t)value->u.u64;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT16:
- return (tb_uint32_t)value->u.u16;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT8:
- return (tb_uint32_t)value->u.u8;
- case TB_DATABASE_SQL_VALUE_TYPE_INT32:
- return (tb_uint32_t)value->u.i32;
- case TB_DATABASE_SQL_VALUE_TYPE_INT64:
- return (tb_uint32_t)value->u.i64;
- case TB_DATABASE_SQL_VALUE_TYPE_INT16:
- return (tb_uint32_t)value->u.i16;
- case TB_DATABASE_SQL_VALUE_TYPE_INT8:
- return (tb_uint32_t)value->u.i8;
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- case TB_DATABASE_SQL_VALUE_TYPE_FLOAT:
- return (tb_uint32_t)value->u.f;
- case TB_DATABASE_SQL_VALUE_TYPE_DOUBLE:
- return (tb_uint32_t)value->u.d;
-#endif
- case TB_DATABASE_SQL_VALUE_TYPE_TEXT:
- return value->u.text.data? (tb_uint32_t)tb_stoi32(value->u.text.data) : 0;
- default:
- tb_trace_e("unknown number type: %lu", value->type);
- break;
- }
-
- return 0;
-}
-tb_uint64_t tb_database_sql_value_uint64(tb_database_sql_value_t const* value)
-{
- // check
- tb_assert_and_check_return_val(value, 0);
-
- // done
- switch (value->type)
- {
- case TB_DATABASE_SQL_VALUE_TYPE_UINT64:
- return (tb_uint64_t)value->u.u64;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT32:
- return (tb_uint64_t)value->u.u32;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT16:
- return (tb_uint64_t)value->u.u16;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT8:
- return (tb_uint64_t)value->u.u8;
- case TB_DATABASE_SQL_VALUE_TYPE_INT64:
- return (tb_uint64_t)value->u.i64;
- case TB_DATABASE_SQL_VALUE_TYPE_INT32:
- return (tb_uint64_t)value->u.i32;
- case TB_DATABASE_SQL_VALUE_TYPE_INT16:
- return (tb_uint64_t)value->u.i16;
- case TB_DATABASE_SQL_VALUE_TYPE_INT8:
- return (tb_uint64_t)value->u.i8;
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- case TB_DATABASE_SQL_VALUE_TYPE_FLOAT:
- return (tb_uint64_t)value->u.f;
- case TB_DATABASE_SQL_VALUE_TYPE_DOUBLE:
- return (tb_uint64_t)value->u.d;
-#endif
- case TB_DATABASE_SQL_VALUE_TYPE_TEXT:
- return value->u.text.data? (tb_uint64_t)tb_stou64(value->u.text.data) : 0;
- default:
- tb_trace_e("unknown number type: %lu", value->type);
- break;
- }
-
- return 0;
-}
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
-tb_float_t tb_database_sql_value_float(tb_database_sql_value_t const* value)
-{
- // check
- tb_assert_and_check_return_val(value, 0);
-
- // done
- switch (value->type)
- {
- case TB_DATABASE_SQL_VALUE_TYPE_FLOAT:
- return value->u.f;
- case TB_DATABASE_SQL_VALUE_TYPE_DOUBLE:
- return (tb_float_t)value->u.d;
- case TB_DATABASE_SQL_VALUE_TYPE_INT64:
- return (tb_float_t)value->u.i64;
- case TB_DATABASE_SQL_VALUE_TYPE_INT32:
- return (tb_float_t)value->u.i32;
- case TB_DATABASE_SQL_VALUE_TYPE_INT16:
- return (tb_float_t)value->u.i16;
- case TB_DATABASE_SQL_VALUE_TYPE_INT8:
- return (tb_float_t)value->u.i8;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT64:
- return (tb_float_t)value->u.u64;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT32:
- return (tb_float_t)value->u.u32;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT16:
- return (tb_float_t)value->u.u16;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT8:
- return (tb_float_t)value->u.u8;
- case TB_DATABASE_SQL_VALUE_TYPE_TEXT:
- return value->u.text.data? tb_stof(value->u.text.data) : 0;
- default:
- tb_trace_e("unknown number type: %lu", value->type);
- break;
- }
-
- return 0;
-}
-tb_double_t tb_database_sql_value_double(tb_database_sql_value_t const* value)
-{
- // check
- tb_assert_and_check_return_val(value, 0);
-
- // done
- switch (value->type)
- {
- case TB_DATABASE_SQL_VALUE_TYPE_FLOAT:
- return (tb_double_t)value->u.f;
- case TB_DATABASE_SQL_VALUE_TYPE_DOUBLE:
- return value->u.d;
- case TB_DATABASE_SQL_VALUE_TYPE_INT64:
- return (tb_double_t)value->u.i64;
- case TB_DATABASE_SQL_VALUE_TYPE_INT32:
- return (tb_double_t)value->u.i32;
- case TB_DATABASE_SQL_VALUE_TYPE_INT16:
- return (tb_double_t)value->u.i16;
- case TB_DATABASE_SQL_VALUE_TYPE_INT8:
- return (tb_double_t)value->u.i8;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT64:
- return (tb_double_t)value->u.u64;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT32:
- return (tb_double_t)value->u.u32;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT16:
- return (tb_double_t)value->u.u16;
- case TB_DATABASE_SQL_VALUE_TYPE_UINT8:
- return (tb_double_t)value->u.u8;
- case TB_DATABASE_SQL_VALUE_TYPE_TEXT:
- return value->u.text.data? tb_stod(value->u.text.data) : 0;
- default:
- tb_trace_e("unknown number type: %lu", value->type);
- break;
- }
-
- return 0;
-}
-#endif
-tb_void_t tb_database_sql_value_set_null(tb_database_sql_value_t* value)
-{
- // check
- tb_assert_and_check_return(value);
-
- // init null
- value->type = TB_DATABASE_SQL_VALUE_TYPE_NULL;
-}
-tb_void_t tb_database_sql_value_set_int8(tb_database_sql_value_t* value, tb_int8_t number)
-{
- // check
- tb_assert_and_check_return(value);
-
- // init number
- value->type = TB_DATABASE_SQL_VALUE_TYPE_INT8;
- value->u.i8 = number;
-}
-tb_void_t tb_database_sql_value_set_int16(tb_database_sql_value_t* value, tb_int16_t number)
-{
- // check
- tb_assert_and_check_return(value);
-
- // init number
- value->type = TB_DATABASE_SQL_VALUE_TYPE_INT16;
- value->u.i16 = number;
-}
-tb_void_t tb_database_sql_value_set_int32(tb_database_sql_value_t* value, tb_int32_t number)
-{
- // check
- tb_assert_and_check_return(value);
-
- // init number
- value->type = TB_DATABASE_SQL_VALUE_TYPE_INT32;
- value->u.i32 = number;
-}
-tb_void_t tb_database_sql_value_set_int64(tb_database_sql_value_t* value, tb_int64_t number)
-{
- // check
- tb_assert_and_check_return(value);
-
- // init number
- value->type = TB_DATABASE_SQL_VALUE_TYPE_INT64;
- value->u.i64 = number;
-}
-tb_void_t tb_database_sql_value_set_uint8(tb_database_sql_value_t* value, tb_uint8_t number)
-{
- // check
- tb_assert_and_check_return(value);
-
- // init number
- value->type = TB_DATABASE_SQL_VALUE_TYPE_INT8;
- value->u.u8 = number;
-}
-tb_void_t tb_database_sql_value_set_uint16(tb_database_sql_value_t* value, tb_uint16_t number)
-{
- // check
- tb_assert_and_check_return(value);
-
- // init number
- value->type = TB_DATABASE_SQL_VALUE_TYPE_INT16;
- value->u.u16 = number;
-}
-tb_void_t tb_database_sql_value_set_uint32(tb_database_sql_value_t* value, tb_uint32_t number)
-{
- // check
- tb_assert_and_check_return(value);
-
- // init number
- value->type = TB_DATABASE_SQL_VALUE_TYPE_INT32;
- value->u.u32 = number;
-}
-tb_void_t tb_database_sql_value_set_uint64(tb_database_sql_value_t* value, tb_uint64_t number)
-{
- // check
- tb_assert_and_check_return(value);
-
- // init number
- value->type = TB_DATABASE_SQL_VALUE_TYPE_INT64;
- value->u.u64 = number;
-}
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
-tb_void_t tb_database_sql_value_set_float(tb_database_sql_value_t* value, tb_float_t number)
-{
- // check
- tb_assert_and_check_return(value);
-
- // init number
- value->type = TB_DATABASE_SQL_VALUE_TYPE_FLOAT;
- value->u.f = number;
-}
-tb_void_t tb_database_sql_value_set_double(tb_database_sql_value_t* value, tb_double_t number)
-{
- // check
- tb_assert_and_check_return(value);
-
- // init number
- value->type = TB_DATABASE_SQL_VALUE_TYPE_DOUBLE;
- value->u.d = number;
-}
-#endif
-tb_void_t tb_database_sql_value_set_text(tb_database_sql_value_t* value, tb_char_t const* text, tb_size_t hint)
-{
- // check
- tb_assert_and_check_return(value);
-
- // init text
- value->type = TB_DATABASE_SQL_VALUE_TYPE_TEXT;
- value->u.text.data = text;
- value->u.text.hint = hint;
-}
-tb_void_t tb_database_sql_value_set_blob8(tb_database_sql_value_t* value, tb_byte_t const* data, tb_size_t size)
-{
- // check
- tb_assert_and_check_return(value);
-
- // init blob
- value->type = TB_DATABASE_SQL_VALUE_TYPE_BLOB8;
- value->u.blob.data = data;
- value->u.blob.size = size;
- value->u.blob.stream = tb_null;
-
- // check size
- tb_assert(tb_database_sql_value_size(value) <= TB_MAXU8);
-}
-tb_void_t tb_database_sql_value_set_blob16(tb_database_sql_value_t* value, tb_byte_t const* data, tb_size_t size)
-{
- // check
- tb_assert_and_check_return(value);
-
- // init blob
- value->type = TB_DATABASE_SQL_VALUE_TYPE_BLOB16;
- value->u.blob.data = data;
- value->u.blob.size = size;
- value->u.blob.stream = tb_null;
-
- // check size
- tb_assert(tb_database_sql_value_size(value) <= TB_MAXU16);
-}
-tb_void_t tb_database_sql_value_set_blob32(tb_database_sql_value_t* value, tb_byte_t const* data, tb_size_t size, tb_stream_ref_t stream)
-{
- // check
- tb_assert_and_check_return(value);
-
- // check stream
- tb_hong_t stream_size = 0;
- if (stream)
- {
- // must be opened
- tb_assert_and_check_return(tb_stream_is_opened(stream));
-
- // the stream size
- stream_size = tb_stream_size(stream);
- tb_assert_and_check_return(stream_size >= 0 && stream_size < TB_MAXS32);
- }
-
- // init blob
- value->type = TB_DATABASE_SQL_VALUE_TYPE_BLOB32;
- value->u.blob.data = data;
- value->u.blob.size = data? size : (tb_size_t)stream_size;
- value->u.blob.stream = stream;
-
- // check size
- tb_assert(tb_database_sql_value_size(value) <= TB_MAXU32);
-}
diff --git a/core/src/tbox/src/tbox/database/value.h b/core/src/tbox/src/tbox/database/value.h
deleted file mode 100644
index 9c41e65ad..000000000
--- a/core/src/tbox/src/tbox/database/value.h
+++ /dev/null
@@ -1,463 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file value.h
- * @ingroup database
- *
- */
-#ifndef TB_DATABASE_SQL_VALUE_H
-#define TB_DATABASE_SQL_VALUE_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-#include "../stream/stream.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the sql database value type enum
-typedef enum __tb_database_sql_value_type_e
-{
- TB_DATABASE_SQL_VALUE_TYPE_NULL = 0
-, TB_DATABASE_SQL_VALUE_TYPE_INT8 = 1
-, TB_DATABASE_SQL_VALUE_TYPE_INT16 = 2
-, TB_DATABASE_SQL_VALUE_TYPE_INT32 = 3
-, TB_DATABASE_SQL_VALUE_TYPE_INT64 = 4
-, TB_DATABASE_SQL_VALUE_TYPE_UINT8 = 5
-, TB_DATABASE_SQL_VALUE_TYPE_UINT16 = 6
-, TB_DATABASE_SQL_VALUE_TYPE_UINT32 = 7
-, TB_DATABASE_SQL_VALUE_TYPE_UINT64 = 8
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
-, TB_DATABASE_SQL_VALUE_TYPE_FLOAT = 13
-, TB_DATABASE_SQL_VALUE_TYPE_DOUBLE = 14
-#endif
-, TB_DATABASE_SQL_VALUE_TYPE_BLOB8 = 9
-, TB_DATABASE_SQL_VALUE_TYPE_BLOB16 = 10
-, TB_DATABASE_SQL_VALUE_TYPE_BLOB32 = 11
-, TB_DATABASE_SQL_VALUE_TYPE_TEXT = 12
-
-}tb_database_sql_value_type_e;
-
-/// the sql database value type
-typedef struct __tb_database_sql_value_t
-{
- /// the type
- tb_size_t type;
-
- /// the name
- tb_char_t const* name;
-
- /// the data
- union
- {
- // int
- tb_int8_t i8;
- tb_int16_t i16;
- tb_int32_t i32;
- tb_int64_t i64;
-
- // uint
- tb_uint8_t u8;
- tb_uint16_t u16;
- tb_uint32_t u32;
- tb_uint64_t u64;
-
- // float
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- tb_float_t f;
- tb_double_t d;
-#endif
-
- // blob
- struct
- {
- tb_byte_t const* data;
- tb_size_t size;
-
- // the stream for blob32
- tb_stream_ref_t stream;
-
- } blob;
-
- // text
- struct
- {
- tb_char_t const* data;
- tb_size_t hint;
-
- } text;
-
- }u;
-
-}tb_database_sql_value_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! the value data size
- *
- * @param value the value
- *
- * @return the value data size
- */
-tb_size_t tb_database_sql_value_size(tb_database_sql_value_t const* value);
-
-/*! the int8 value
- *
- * @param value the value
- *
- * @return the int8 value
- */
-tb_int8_t tb_database_sql_value_int8(tb_database_sql_value_t const* value);
-
-/*! the int16 value
- *
- * @param value the value
- *
- * @return the int16 value
- */
-tb_int16_t tb_database_sql_value_int16(tb_database_sql_value_t const* value);
-
-/*! the int32 value
- *
- * @param value the value
- *
- * @return the int32 value
- */
-tb_int32_t tb_database_sql_value_int32(tb_database_sql_value_t const* value);
-
-/*! the int64 value
- *
- * @param value the value
- *
- * @return the int64 value
- */
-tb_int64_t tb_database_sql_value_int64(tb_database_sql_value_t const* value);
-
-/*! the uint8 value
- *
- * @param value the value
- *
- * @return the uint8 value
- */
-tb_uint8_t tb_database_sql_value_uint8(tb_database_sql_value_t const* value);
-
-/*! the uint16 value
- *
- * @param value the value
- *
- * @return the uint16 value
- */
-tb_uint16_t tb_database_sql_value_uint16(tb_database_sql_value_t const* value);
-
-/*! the uint32 value
- *
- * @param value the value
- *
- * @return the uint32 value
- */
-tb_uint32_t tb_database_sql_value_uint32(tb_database_sql_value_t const* value);
-
-/*! the uint64 value
- *
- * @param value the value
- *
- * @return the uint64 value
- */
-tb_uint64_t tb_database_sql_value_uint64(tb_database_sql_value_t const* value);
-
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
-/*! the float value
- *
- * @param value the value
- *
- * @return the float value
- */
-tb_float_t tb_database_sql_value_float(tb_database_sql_value_t const* value);
-
-/*! the double value
- *
- * @param value the value
- *
- * @return the double value
- */
-tb_double_t tb_database_sql_value_double(tb_database_sql_value_t const* value);
-#endif
-
-/*! set the null value
- *
- * @param value the value
- * @param number the number
- */
-tb_void_t tb_database_sql_value_set_null(tb_database_sql_value_t* value);
-
-/*! set the int8 value
- *
- * @param value the value
- * @param number the number
- */
-tb_void_t tb_database_sql_value_set_int8(tb_database_sql_value_t* value, tb_int8_t number);
-
-/*! set the int16 value
- *
- * @param value the value
- * @param number the number
- */
-tb_void_t tb_database_sql_value_set_int16(tb_database_sql_value_t* value, tb_int16_t number);
-
-/*! set the int32 value
- *
- * @param value the value
- * @param number the number
- */
-tb_void_t tb_database_sql_value_set_int32(tb_database_sql_value_t* value, tb_int32_t number);
-
-/*! set the int64 value
- *
- * @param value the value
- * @param number the number
- */
-tb_void_t tb_database_sql_value_set_int64(tb_database_sql_value_t* value, tb_int64_t number);
-
-/*! set the uint8 value
- *
- * @param value the value
- * @param number the number
- */
-tb_void_t tb_database_sql_value_set_uint8(tb_database_sql_value_t* value, tb_uint8_t number);
-
-/*! set the uint16 value
- *
- * @param value the value
- * @param number the number
- */
-tb_void_t tb_database_sql_value_set_uint16(tb_database_sql_value_t* value, tb_uint16_t number);
-
-/*! set the uint32 value
- *
- * @param value the value
- * @param number the number
- */
-tb_void_t tb_database_sql_value_set_uint32(tb_database_sql_value_t* value, tb_uint32_t number);
-
-/*! set the uint64 value
- *
- * @param value the value
- * @param number the number
- */
-tb_void_t tb_database_sql_value_set_uint64(tb_database_sql_value_t* value, tb_uint64_t number);
-
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
-/*! set the float value
- *
- * @param value the value
- * @param number the number
- */
-tb_void_t tb_database_sql_value_set_float(tb_database_sql_value_t* value, tb_float_t number);
-
-/*! set the double value
- *
- * @param value the value
- * @param number the number
- */
-tb_void_t tb_database_sql_value_set_double(tb_database_sql_value_t* value, tb_double_t number);
-#endif
-
-/*! set the text value
- *
- * @param value the value
- * @param text the text data
- * @param hint the text size hint
- */
-tb_void_t tb_database_sql_value_set_text(tb_database_sql_value_t* value, tb_char_t const* text, tb_size_t hint);
-
-/*! set the blob8 value
- *
- * @param value the value
- * @param data the blob data
- * @param size the blob size
- */
-tb_void_t tb_database_sql_value_set_blob8(tb_database_sql_value_t* value, tb_byte_t const* data, tb_size_t size);
-
-/*! set the blob16 value
- *
- * @param value the value
- * @param data the blob data
- * @param size the blob size
- */
-tb_void_t tb_database_sql_value_set_blob16(tb_database_sql_value_t* value, tb_byte_t const* data, tb_size_t size);
-
-/*! set the blob32 value
- *
- * @param value the value
- * @param data the blob data
- * @param size the blob size
- * @param stream the stream, using it if data == null
- */
-tb_void_t tb_database_sql_value_set_blob32(tb_database_sql_value_t* value, tb_byte_t const* data, tb_size_t size, tb_stream_ref_t stream);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * inlines
- */
-
-/// the value is null?
-static __tb_inline_force__ tb_bool_t tb_database_sql_value_is_null(tb_database_sql_value_t const* value)
-{
- return (value && value->type == TB_DATABASE_SQL_VALUE_TYPE_NULL)? tb_true : tb_false;
-}
-
-/// the value is text?
-static __tb_inline_force__ tb_bool_t tb_database_sql_value_is_text(tb_database_sql_value_t const* value)
-{
- return (value && value->type == TB_DATABASE_SQL_VALUE_TYPE_TEXT)? tb_true : tb_false;
-}
-
-/// the value is blob?
-static __tb_inline_force__ tb_bool_t tb_database_sql_value_is_blob(tb_database_sql_value_t const* value)
-{
- return ( value
- && ( value->type == TB_DATABASE_SQL_VALUE_TYPE_BLOB32
- || value->type == TB_DATABASE_SQL_VALUE_TYPE_BLOB16
- || value->type == TB_DATABASE_SQL_VALUE_TYPE_BLOB8))? tb_true : tb_false;
-}
-
-/// the value is blob32?
-static __tb_inline_force__ tb_bool_t tb_database_sql_value_is_blob32(tb_database_sql_value_t const* value)
-{
- return (value && value->type == TB_DATABASE_SQL_VALUE_TYPE_BLOB32)? tb_true : tb_false;
-}
-/// the value is integer?
-static __tb_inline_force__ tb_bool_t tb_database_sql_value_is_integer(tb_database_sql_value_t const* value)
-{
- return (value && value->type >= TB_DATABASE_SQL_VALUE_TYPE_INT8 && value->type <= TB_DATABASE_SQL_VALUE_TYPE_UINT64)? tb_true : tb_false;
-}
-
-/// the value is float?
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
-static __tb_inline_force__ tb_bool_t tb_database_sql_value_is_float(tb_database_sql_value_t const* value)
-{
- return ( value
- && ( value->type == TB_DATABASE_SQL_VALUE_TYPE_FLOAT
- || value->type == TB_DATABASE_SQL_VALUE_TYPE_DOUBLE))? tb_true : tb_false;
-}
-#endif
-
-/// the value is number?
-static __tb_inline_force__ tb_bool_t tb_database_sql_value_is_number(tb_database_sql_value_t const* value)
-{
- return (value && value->type >= TB_DATABASE_SQL_VALUE_TYPE_INT8 && value->type < TB_DATABASE_SQL_VALUE_TYPE_BLOB8)? tb_true : tb_false;
-}
-
-/// the value type
-static __tb_inline_force__ tb_size_t tb_database_sql_value_type(tb_database_sql_value_t const* value)
-{
- // check
- tb_assert_and_check_return_val(value, TB_DATABASE_SQL_VALUE_TYPE_NULL);
-
- // the type
- return value->type;
-}
-
-/// the value name
-static __tb_inline_force__ tb_char_t const* tb_database_sql_value_name(tb_database_sql_value_t const* value)
-{
- // check
- tb_assert_and_check_return_val(value, tb_null);
-
- // the name
- return value->name;
-}
-
-/// the value text data
-static __tb_inline_force__ tb_char_t const* tb_database_sql_value_text(tb_database_sql_value_t const* value)
-{
- // check
- tb_assert_and_check_return_val(value, tb_null);
-
- // is text?
- if (tb_database_sql_value_is_text(value))
- return value->u.text.data;
- // is blob?
- else if (tb_database_sql_value_is_blob(value))
- return (tb_char_t const*)value->u.blob.data;
- // is null?
- else if (tb_database_sql_value_is_null(value))
- return tb_null;
-
- // trace
- tb_trace_e("not text value type: %lu", value->type);
- return tb_null;
-}
-
-/// the value blob data
-static __tb_inline_force__ tb_byte_t const* tb_database_sql_value_blob(tb_database_sql_value_t const* value)
-{
- // check
- tb_assert_and_check_return_val(value, tb_null);
-
- // is blob?
- if (tb_database_sql_value_is_blob(value))
- return value->u.blob.data;
- // is text?
- else if (tb_database_sql_value_is_text(value))
- return (tb_byte_t const*)value->u.text.data;
- // is null?
- else if (tb_database_sql_value_is_null(value))
- return tb_null;
-
- // trace
- tb_trace_e("not blob value type: %lu", value->type);
- return tb_null;
-}
-
-/// the value blob stream
-static __tb_inline_force__ tb_stream_ref_t tb_database_sql_value_blob_stream(tb_database_sql_value_t const* value)
-{
- // the blob stream
- return tb_database_sql_value_is_blob(value)? value->u.blob.stream : tb_null;
-}
-
-/// set the value name
-static __tb_inline_force__ tb_void_t tb_database_sql_value_name_set(tb_database_sql_value_t* value, tb_char_t const* name)
-{
- // check
- tb_assert_and_check_return(value);
-
- // set the name
- value->name = name;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-
-#endif
diff --git a/core/src/tbox/src/tbox/object/array.c b/core/src/tbox/src/tbox/object/array.c
deleted file mode 100644
index f484a5761..000000000
--- a/core/src/tbox/src/tbox/object/array.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file array.c
- * @ingroup object
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "oc_array"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "object.h"
-#include "../algorithm/algorithm.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the array type
-typedef struct __tb_oc_array_t
-{
- // the object base
- tb_object_t base;
-
- // the vector
- tb_vector_ref_t vector;
-
- // is increase refn?
- tb_bool_t incr;
-
-}tb_oc_array_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static __tb_inline__ tb_oc_array_t* tb_oc_array_cast(tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return_val(object && object->type == TB_OBJECT_TYPE_ARRAY, tb_null);
-
- // cast
- return (tb_oc_array_t*)object;
-}
-static tb_object_ref_t tb_oc_array_copy(tb_object_ref_t object)
-{
- // check
- tb_oc_array_t* array = tb_oc_array_cast(object);
- tb_assert_and_check_return_val(array && array->vector, tb_null);
-
- // init copy
- tb_oc_array_t* copy = (tb_oc_array_t*)tb_oc_array_init(tb_vector_grow(array->vector), array->incr);
- tb_assert_and_check_return_val(copy && copy->vector, tb_null);
-
- // refn++
- tb_for_all (tb_object_ref_t, item, array->vector)
- {
- if (item) tb_object_retain(item);
- }
-
- // copy
- tb_vector_copy(copy->vector, array->vector);
-
- // ok
- return (tb_object_ref_t)copy;
-}
-static tb_void_t tb_oc_array_exit(tb_object_ref_t object)
-{
- // check
- tb_oc_array_t* array = tb_oc_array_cast(object);
- tb_assert_and_check_return(array);
-
- // exit vector
- if (array->vector) tb_vector_exit(array->vector);
- array->vector = tb_null;
-
- // exit it
- tb_free(array);
-}
-static tb_void_t tb_oc_array_clear(tb_object_ref_t object)
-{
- tb_oc_array_t* array = tb_oc_array_cast(object);
- tb_assert_and_check_return(array && array->vector);
-
- // clear vector
- tb_vector_clear(array->vector);
-}
-static tb_oc_array_t* tb_oc_array_init_base()
-{
- // done
- tb_bool_t ok = tb_false;
- tb_oc_array_t* array = tb_null;
- do
- {
- // make array
- array = tb_malloc0_type(tb_oc_array_t);
- tb_assert_and_check_break(array);
-
- // init array
- if (!tb_object_init((tb_object_ref_t)array, TB_OBJECT_FLAG_NONE, TB_OBJECT_TYPE_ARRAY)) break;
-
- // init base
- array->base.copy = tb_oc_array_copy;
- array->base.exit = tb_oc_array_exit;
- array->base.clear = tb_oc_array_clear;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (array) tb_object_exit((tb_object_ref_t)array);
- array = tb_null;
- }
-
- // ok?
- return array;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-tb_object_ref_t tb_oc_array_init(tb_size_t grow, tb_bool_t incr)
-{
- // done
- tb_bool_t ok = tb_false;
- tb_oc_array_t* array = tb_null;
- do
- {
- // make array
- array = tb_oc_array_init_base();
- tb_assert_and_check_break(array);
-
- // init element
- tb_element_t element = tb_element_obj();
-
- // init vector
- array->vector = tb_vector_init(grow, element);
- tb_assert_and_check_break(array->vector);
-
- // init incr
- array->incr = incr;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed
- if (!ok)
- {
- // exit it
- if (array) tb_oc_array_exit((tb_object_ref_t)array);
- array = tb_null;
- }
-
- // ok?
- return (tb_object_ref_t)array;
-}
-tb_size_t tb_oc_array_size(tb_object_ref_t object)
-{
- // check
- tb_oc_array_t* array = tb_oc_array_cast(object);
- tb_assert_and_check_return_val(array && array->vector, 0);
-
- // size
- return tb_vector_size(array->vector);
-}
-tb_object_ref_t tb_oc_array_item(tb_object_ref_t object, tb_size_t index)
-{
- // check
- tb_oc_array_t* array = tb_oc_array_cast(object);
- tb_assert_and_check_return_val(array && array->vector, tb_null);
-
- // item
- return (tb_object_ref_t)tb_iterator_item(array->vector, index);
-}
-tb_iterator_ref_t tb_oc_array_itor(tb_object_ref_t object)
-{
- // check
- tb_oc_array_t* array = tb_oc_array_cast(object);
- tb_assert_and_check_return_val(array, tb_null);
-
- // iterator
- return (tb_iterator_ref_t)array->vector;
-}
-tb_void_t tb_oc_array_remove(tb_object_ref_t object, tb_size_t index)
-{
- // check
- tb_oc_array_t* array = tb_oc_array_cast(object);
- tb_assert_and_check_return(array && array->vector);
-
- // remove
- tb_vector_remove(array->vector, index);
-}
-tb_void_t tb_oc_array_append(tb_object_ref_t object, tb_object_ref_t item)
-{
- // check
- tb_oc_array_t* array = tb_oc_array_cast(object);
- tb_assert_and_check_return(array && array->vector && item);
-
- // insert
- tb_vector_insert_tail(array->vector, item);
-
- // refn--
- if (!array->incr) tb_object_exit(item);
-}
-tb_void_t tb_oc_array_insert(tb_object_ref_t object, tb_size_t index, tb_object_ref_t item)
-{
- // check
- tb_oc_array_t* array = tb_oc_array_cast(object);
- tb_assert_and_check_return(array && array->vector && item);
-
- // insert
- tb_vector_insert_prev(array->vector, index, item);
-
- // refn--
- if (!array->incr) tb_object_exit(item);
-}
-tb_void_t tb_oc_array_replace(tb_object_ref_t object, tb_size_t index, tb_object_ref_t item)
-{
- // check
- tb_oc_array_t* array = tb_oc_array_cast(object);
- tb_assert_and_check_return(array && array->vector && item);
-
- // replace
- tb_vector_replace(array->vector, index, item);
-
- // refn--
- if (!array->incr) tb_object_exit(item);
-}
-tb_void_t tb_oc_array_incr(tb_object_ref_t object, tb_bool_t incr)
-{
- // check
- tb_oc_array_t* array = tb_oc_array_cast(object);
- tb_assert_and_check_return(array);
-
- array->incr = incr;
-}
diff --git a/core/src/tbox/src/tbox/object/array.h b/core/src/tbox/src/tbox/object/array.h
deleted file mode 100644
index cfac90d82..000000000
--- a/core/src/tbox/src/tbox/object/array.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file array.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_ARRAY_H
-#define TB_OBJECT_ARRAY_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init array
- *
- * @param grow the array grow
- * @param incr is increase refn?
- *
- * @return the array object
- */
-tb_object_ref_t tb_oc_array_init(tb_size_t grow, tb_bool_t incr);
-
-/*! the array size
- *
- * @param array the array object
- *
- * @return the array size
- */
-tb_size_t tb_oc_array_size(tb_object_ref_t array);
-
-/*! the array item at index
- *
- * @param array the array object
- * @param index the array index
- *
- * @return the array item
- */
-tb_object_ref_t tb_oc_array_item(tb_object_ref_t array, tb_size_t index);
-
-/*! set the array incr
- *
- * @param array the array object
- * @param incr is increase refn?
- */
-tb_void_t tb_oc_array_incr(tb_object_ref_t array, tb_bool_t incr);
-
-/*! the array iterator
- *
- * @param array the array object
- *
- * @return the array iterator
- *
- * @code
- * tb_for_all (tb_object_ref_t, item, tb_oc_array_itor(array))
- * {
- * if (item)
- * {
- * // ...
- * }
- * }
- * @endcode
- */
-tb_iterator_ref_t tb_oc_array_itor(tb_object_ref_t array);
-
-/*! remove the item from index
- *
- * @param array the array object
- * @param index the array index
- */
-tb_void_t tb_oc_array_remove(tb_object_ref_t array, tb_size_t index);
-
-/*! append item to array
- *
- * @param array the array object
- * @param index the array index
- */
-tb_void_t tb_oc_array_append(tb_object_ref_t array, tb_object_ref_t item);
-
-/*! insert item to array
- *
- * @param array the array object
- * @param index the array index
- * @param item the array item
- */
-tb_void_t tb_oc_array_insert(tb_object_ref_t array, tb_size_t index, tb_object_ref_t item);
-
-/*! replace item to array
- *
- * @param array the array object
- * @param index the array index
- * @param item the array item
- */
-tb_void_t tb_oc_array_replace(tb_object_ref_t array, tb_size_t index, tb_object_ref_t item);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/boolean.c b/core/src/tbox/src/tbox/object/boolean.c
deleted file mode 100644
index 4e32ec5c2..000000000
--- a/core/src/tbox/src/tbox/object/boolean.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file boolean.c
- * @ingroup object
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "oc_boolean"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "object.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the boolean type
-typedef struct __tb_oc_boolean_t
-{
- // the object base
- tb_object_t base;
-
- // the boolean value
- tb_bool_t value;
-
-}tb_oc_boolean_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static __tb_inline__ tb_oc_boolean_t* tb_oc_boolean_cast(tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return_val(object && object->type == TB_OBJECT_TYPE_BOOLEAN, tb_null);
-
- // cast
- return (tb_oc_boolean_t*)object;
-}
-
-static tb_object_ref_t tb_oc_boolean_copy(tb_object_ref_t object)
-{
- // check
- tb_oc_boolean_t* boolean = (tb_oc_boolean_t*)object;
- tb_assert_and_check_return_val(boolean, tb_null);
-
- // copy
- return object;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * globals
- */
-
-// true
-static tb_oc_boolean_t const g_boolean_true =
-{
- {
- TB_OBJECT_FLAG_READONLY | TB_OBJECT_FLAG_SINGLETON
- , TB_OBJECT_TYPE_BOOLEAN
- , 1
- , tb_null
- , tb_oc_boolean_copy
- , tb_null
- , tb_null
- }
-, tb_true
-
-};
-
-// false
-static tb_oc_boolean_t const g_boolean_false =
-{
- {
- TB_OBJECT_FLAG_READONLY | TB_OBJECT_FLAG_SINGLETON
- , TB_OBJECT_TYPE_BOOLEAN
- , 1
- , tb_null
- , tb_oc_boolean_copy
- , tb_null
- , tb_null
- }
-, tb_false
-
-};
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-tb_object_ref_t tb_oc_boolean_init(tb_bool_t value)
-{
- return value? tb_oc_boolean_true() : tb_oc_boolean_false();
-}
-tb_object_ref_t tb_oc_boolean_true()
-{
- return (tb_object_ref_t)&g_boolean_true;
-}
-tb_object_ref_t tb_oc_boolean_false()
-{
- return (tb_object_ref_t)&g_boolean_false;
-}
-tb_bool_t tb_oc_boolean_bool(tb_object_ref_t object)
-{
- tb_oc_boolean_t* boolean = tb_oc_boolean_cast(object);
- tb_assert_and_check_return_val(boolean, tb_false);
-
- return boolean->value;
-}
-
diff --git a/core/src/tbox/src/tbox/object/boolean.h b/core/src/tbox/src/tbox/object/boolean.h
deleted file mode 100644
index 6926edb56..000000000
--- a/core/src/tbox/src/tbox/object/boolean.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file boolean.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_BOOLEAN_H
-#define TB_OBJECT_BOOLEAN_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init boolean
- *
- * @param value the value
- *
- * @return the boolean object
- */
-tb_object_ref_t tb_oc_boolean_init(tb_bool_t value);
-
-/*! the boolean value: true
- *
- * @return the boolean object
- */
-tb_object_ref_t tb_oc_boolean_true(tb_noarg_t);
-
-/*! the boolean value: false
- *
- * @return the boolean object
- */
-tb_object_ref_t tb_oc_boolean_false(tb_noarg_t);
-
-/*! the boolean value
- *
- * @param the boolean object
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_boolean_bool(tb_object_ref_t boolean);
-
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/data.c b/core/src/tbox/src/tbox/object/data.c
deleted file mode 100644
index c152d241e..000000000
--- a/core/src/tbox/src/tbox/object/data.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file data.c
- * @ingroup object
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "oc_data"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "object.h"
-#include "../utils/utils.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the data type
-typedef struct __tb_oc_data_t
-{
- // the object base
- tb_object_t base;
-
- // the data buffer
- tb_buffer_t buffer;
-
-}tb_oc_data_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static __tb_inline__ tb_oc_data_t* tb_oc_data_cast(tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return_val(object && object->type == TB_OBJECT_TYPE_DATA, tb_null);
-
- // cast
- return (tb_oc_data_t*)object;
-}
-static tb_object_ref_t tb_oc_data_copy(tb_object_ref_t object)
-{
- return tb_oc_data_init_from_data(tb_oc_data_getp(object), tb_oc_data_size(object));
-}
-static tb_void_t tb_oc_data_exit(tb_object_ref_t object)
-{
- tb_oc_data_t* data = tb_oc_data_cast(object);
- if (data)
- {
- tb_buffer_exit(&data->buffer);
- tb_free(data);
- }
-}
-static tb_void_t tb_oc_data_clear(tb_object_ref_t object)
-{
- tb_oc_data_t* data = tb_oc_data_cast(object);
- if (data) tb_buffer_clear(&data->buffer);
-}
-static tb_oc_data_t* tb_oc_data_init_base()
-{
- // done
- tb_bool_t ok = tb_false;
- tb_oc_data_t* data = tb_null;
- do
- {
- // make data
- data = tb_malloc0_type(tb_oc_data_t);
- tb_assert_and_check_break(data);
-
- // init data
- if (!tb_object_init((tb_object_ref_t)data, TB_OBJECT_FLAG_NONE, TB_OBJECT_TYPE_DATA)) break;
-
- // init base
- data->base.copy = tb_oc_data_copy;
- data->base.exit = tb_oc_data_exit;
- data->base.clear = tb_oc_data_clear;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (data) tb_object_exit((tb_object_ref_t)data);
- data = tb_null;
- }
-
- // ok?
- return data;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-tb_object_ref_t tb_oc_data_init_from_url(tb_char_t const* url)
-{
- // check
- tb_assert_and_check_return_val(url, tb_null);
-
- // init stream
- tb_stream_ref_t stream = tb_stream_init_from_url(url);
- tb_assert_and_check_return_val(stream, tb_null);
-
- // make stream
- tb_object_ref_t object = tb_null;
- if (tb_stream_open(stream))
- {
- // read all data
- tb_size_t size = 0;
- tb_byte_t* data = (tb_byte_t*)tb_stream_bread_all(stream, tb_false, &size);
- if (data)
- {
- // make object
- object = tb_oc_data_init_from_data(data, size);
-
- // exit data
- tb_free(data);
- }
-
- // exit stream
- tb_stream_exit(stream);
- }
-
- // ok?
- return object;
-}
-tb_object_ref_t tb_oc_data_init_from_data(tb_pointer_t addr, tb_size_t size)
-{
- // make
- tb_oc_data_t* data = tb_oc_data_init_base();
- tb_assert_and_check_return_val(data, tb_null);
-
- // init buffer
- if (!tb_buffer_init(&data->buffer))
- {
- tb_oc_data_exit((tb_object_ref_t)data);
- return tb_null;
- }
-
- // copy data
- if (addr && size) tb_buffer_memncpy(&data->buffer, (tb_byte_t const*)addr, size);
-
- // ok
- return (tb_object_ref_t)data;
-}
-tb_object_ref_t tb_oc_data_init_from_buffer(tb_buffer_ref_t pbuf)
-{
- // make
- tb_oc_data_t* data = tb_oc_data_init_base();
- tb_assert_and_check_return_val(data, tb_null);
-
- // init buffer
- if (!tb_buffer_init(&data->buffer))
- {
- tb_oc_data_exit((tb_object_ref_t)data);
- return tb_null;
- }
-
- // copy data
- if (pbuf) tb_buffer_memcpy(&data->buffer, pbuf);
-
- // ok
- return (tb_object_ref_t)data;
-}
-tb_pointer_t tb_oc_data_getp(tb_object_ref_t object)
-{
- // check
- tb_oc_data_t* data = tb_oc_data_cast(object);
- tb_assert_and_check_return_val(data, tb_null);
-
- // data
- return tb_buffer_data(&data->buffer);
-}
-tb_bool_t tb_oc_data_setp(tb_object_ref_t object, tb_pointer_t addr, tb_size_t size)
-{
- // check
- tb_oc_data_t* data = tb_oc_data_cast(object);
- tb_assert_and_check_return_val(data && addr, tb_false);
-
- // data
- tb_buffer_memncpy(&data->buffer, (tb_byte_t const*)addr, size);
-
- // ok
- return tb_true;
-}
-tb_size_t tb_oc_data_size(tb_object_ref_t object)
-{
- // check
- tb_oc_data_t* data = tb_oc_data_cast(object);
- tb_assert_and_check_return_val(data, 0);
-
- // data
- return tb_buffer_size(&data->buffer);
-}
-tb_buffer_ref_t tb_oc_data_buffer(tb_object_ref_t object)
-{
- // check
- tb_oc_data_t* data = tb_oc_data_cast(object);
- tb_assert_and_check_return_val(data, tb_null);
-
- // buffer
- return &data->buffer;
-}
-tb_bool_t tb_oc_data_writ_to_url(tb_object_ref_t object, tb_char_t const* url)
-{
- // check
- tb_oc_data_t* data = tb_oc_data_cast(object);
- tb_assert_and_check_return_val(data && tb_oc_data_getp((tb_object_ref_t)data) && url, tb_false);
-
- // make stream
- tb_stream_ref_t stream = tb_stream_init_from_url(url);
- tb_assert_and_check_return_val(stream, tb_false);
-
- // ctrl
- if (tb_stream_type(stream) == TB_STREAM_TYPE_FILE)
- tb_stream_ctrl(stream, TB_STREAM_CTRL_FILE_SET_MODE, TB_FILE_MODE_WO | TB_FILE_MODE_CREAT | TB_FILE_MODE_TRUNC);
-
- // open stream
- tb_bool_t ok = tb_false;
- if (tb_stream_open(stream))
- {
- // writ stream
- if (tb_stream_bwrit(stream, (tb_byte_t const*)tb_oc_data_getp((tb_object_ref_t)data), tb_oc_data_size((tb_object_ref_t)data))) ok = tb_true;
- }
-
- // exit stream
- tb_stream_exit(stream);
-
- // ok?
- return ok;
-}
diff --git a/core/src/tbox/src/tbox/object/data.h b/core/src/tbox/src/tbox/object/data.h
deleted file mode 100644
index c78fa0b85..000000000
--- a/core/src/tbox/src/tbox/object/data.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file data.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_DATA_H
-#define TB_OBJECT_DATA_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init data from url
- *
- * @param data the data
- * @param size the size
- *
- * @return the data object
- */
-tb_object_ref_t tb_oc_data_init_from_url(tb_char_t const* url);
-
-/*! init data from data
- *
- * @param data the data
- * @param size the size
- *
- * @return the data object
- */
-tb_object_ref_t tb_oc_data_init_from_data(tb_pointer_t data, tb_size_t size);
-
-/*! init data from buffer
- *
- * @param buffer the buffer
- *
- * @return the data object
- */
-tb_object_ref_t tb_oc_data_init_from_buffer(tb_buffer_ref_t buffer);
-
-/*! get the data
- *
- * @param data the data object
- *
- * @return the data address
- */
-tb_pointer_t tb_oc_data_getp(tb_object_ref_t data);
-
-/*! set the data
- *
- * @param data the data object
- * @param addr the data address
- * @param size the data size
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_data_setp(tb_object_ref_t data, tb_pointer_t addr, tb_size_t size);
-
-/*! the data size
- *
- * @param data the data object
- *
- * @return the data size
- */
-tb_size_t tb_oc_data_size(tb_object_ref_t data);
-
-/*! the data buffer
- *
- * @param data the data object
- *
- * @return the data buffer
- */
-tb_buffer_ref_t tb_oc_data_buffer(tb_object_ref_t data);
-
-/*! writ data to url
- *
- * @param data the data object
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_data_writ_to_url(tb_object_ref_t data, tb_char_t const* url);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/date.c b/core/src/tbox/src/tbox/object/date.c
deleted file mode 100644
index c1e24f496..000000000
--- a/core/src/tbox/src/tbox/object/date.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file date.c
- * @ingroup object
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "oc_date"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "object.h"
-#include "../utils/utils.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the date type
-typedef struct __tb_oc_date_t
-{
- // the object base
- tb_object_t base;
-
- // the date time
- tb_time_t time;
-
-}tb_oc_date_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static __tb_inline__ tb_oc_date_t* tb_oc_date_cast(tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return_val(object && object->type == TB_OBJECT_TYPE_DATE, tb_null);
-
- // cast
- return (tb_oc_date_t*)object;
-}
-static tb_object_ref_t tb_oc_date_copy(tb_object_ref_t object)
-{
- return tb_oc_date_init_from_time(tb_oc_date_time(object));
-}
-static tb_void_t tb_oc_date_exit(tb_object_ref_t object)
-{
- if (object) tb_free(object);
-}
-static tb_void_t tb_oc_date_clear(tb_object_ref_t object)
-{
- tb_oc_date_t* date = tb_oc_date_cast(object);
- if (date) date->time = 0;
-}
-static tb_oc_date_t* tb_oc_date_init_base()
-{
- // done
- tb_bool_t ok = tb_false;
- tb_oc_date_t* date = tb_null;
- do
- {
- // make date
- date = tb_malloc0_type(tb_oc_date_t);
- tb_assert_and_check_break(date);
-
- // init date
- if (!tb_object_init((tb_object_ref_t)date, TB_OBJECT_FLAG_NONE, TB_OBJECT_TYPE_DATE)) break;
-
- // init base
- date->base.copy = tb_oc_date_copy;
- date->base.exit = tb_oc_date_exit;
- date->base.clear = tb_oc_date_clear;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (date) tb_object_exit((tb_object_ref_t)date);
- date = tb_null;
- }
-
- // ok?
- return date;
-}
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-tb_object_ref_t tb_oc_date_init_from_now()
-{
- // make
- tb_oc_date_t* date = tb_oc_date_init_base();
- tb_assert_and_check_return_val(date, tb_null);
-
- // init time
- date->time = tb_time();
-
- // ok
- return (tb_object_ref_t)date;
-}
-tb_object_ref_t tb_oc_date_init_from_time(tb_time_t time)
-{
- // make
- tb_oc_date_t* date = tb_oc_date_init_base();
- tb_assert_and_check_return_val(date, tb_null);
-
- // init time
- if (time > 0) date->time = time;
-
- // ok
- return (tb_object_ref_t)date;
-}
-tb_time_t tb_oc_date_time(tb_object_ref_t object)
-{
- // check
- tb_oc_date_t* date = tb_oc_date_cast(object);
- tb_assert_and_check_return_val(date, -1);
-
- // time
- return date->time;
-}
-tb_bool_t tb_oc_date_time_set(tb_object_ref_t object, tb_time_t time)
-{
- // check
- tb_oc_date_t* date = tb_oc_date_cast(object);
- tb_assert_and_check_return_val(date, tb_false);
-
- // set time
- date->time = time;
-
- // ok
- return tb_true;
-}
-tb_bool_t tb_oc_date_time_set_now(tb_object_ref_t object)
-{
- // check
- tb_oc_date_t* date = tb_oc_date_cast(object);
- tb_assert_and_check_return_val(date, tb_false);
-
- // set time
- date->time = tb_time();
-
- // ok
- return tb_true;
-}
diff --git a/core/src/tbox/src/tbox/object/date.h b/core/src/tbox/src/tbox/object/date.h
deleted file mode 100644
index 7046b6499..000000000
--- a/core/src/tbox/src/tbox/object/date.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file date.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_DATE_H
-#define TB_OBJECT_DATE_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init date from now
- *
- * @return the date object
- */
-tb_object_ref_t tb_oc_date_init_from_now(tb_noarg_t);
-
-/*! init date from time
- *
- * @param the date time
- *
- * @return the date object
- */
-tb_object_ref_t tb_oc_date_init_from_time(tb_time_t time);
-
-/*! the date time
- *
- * @param the date object
- *
- * @return the date time
- */
-tb_time_t tb_oc_date_time(tb_object_ref_t date);
-
-/*! set the date time
- *
- * @param the date object
- * @param the date time
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_date_time_set(tb_object_ref_t date, tb_time_t time);
-
-/*! set the date time for now
- *
- * @param the date object
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_date_time_set_now(tb_object_ref_t date);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/deprecated/array.h b/core/src/tbox/src/tbox/object/deprecated/array.h
deleted file mode 100644
index 6819a0ff2..000000000
--- a/core/src/tbox/src/tbox/object/deprecated/array.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file array.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_DEPRECATED_ARRAY_H
-#define TB_OBJECT_DEPRECATED_ARRAY_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-#define tb_object_array_init tb_oc_array_init
-#define tb_object_array_size tb_oc_array_size
-#define tb_object_array_item tb_oc_array_item
-#define tb_object_array_incr tb_oc_array_incr
-#define tb_object_array_itor tb_oc_array_itor
-#define tb_object_array_remove tb_oc_array_remove
-#define tb_object_array_append tb_oc_array_append
-#define tb_object_array_insert tb_oc_array_insert
-#define tb_object_array_replace tb_oc_array_replace
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/deprecated/boolean.h b/core/src/tbox/src/tbox/object/deprecated/boolean.h
deleted file mode 100644
index 8bc8a4d28..000000000
--- a/core/src/tbox/src/tbox/object/deprecated/boolean.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file boolean.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_DEPRECATED_BOOLEAN_H
-#define TB_OBJECT_DEPRECATED_BOOLEAN_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-#define tb_object_boolean_init tb_oc_boolean_init
-#define tb_object_boolean_true tb_oc_boolean_true
-#define tb_object_boolean_false tb_oc_boolean_false
-#define tb_object_boolean_bool tb_oc_boolean_bool
-
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/deprecated/data.h b/core/src/tbox/src/tbox/object/deprecated/data.h
deleted file mode 100644
index eee8a9900..000000000
--- a/core/src/tbox/src/tbox/object/deprecated/data.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file data.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_DEPRECATED_DATA_H
-#define TB_OBJECT_DEPRECATED_DATA_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-#define tb_object_data_init_from_url tb_oc_data_init_from_url
-#define tb_object_data_init_from_data tb_oc_data_init_from_data
-#define tb_object_data_init_from_buffer tb_oc_data_init_from_buffer
-#define tb_object_data_getp tb_oc_data_getp
-#define tb_object_data_setp tb_oc_data_setp
-#define tb_object_data_size tb_oc_data_size
-#define tb_object_data_buffer tb_oc_data_buffer
-#define tb_object_data_writ_to_url tb_oc_data_writ_to_url
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/deprecated/date.h b/core/src/tbox/src/tbox/object/deprecated/date.h
deleted file mode 100644
index c4a0a7a82..000000000
--- a/core/src/tbox/src/tbox/object/deprecated/date.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file date.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_DEPRECATED_DATE_H
-#define TB_OBJECT_DEPRECATED_DATE_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-#define tb_object_date_init_from_now tb_oc_date_init_from_now
-#define tb_object_date_init_from_time tb_oc_date_init_from_time
-#define tb_object_date_time tb_oc_date_time
-#define tb_object_date_time_set tb_oc_date_time_set
-#define tb_object_date_time_set_now tb_oc_date_time_set_now
-
-
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/deprecated/deprecated.h b/core/src/tbox/src/tbox/object/deprecated/deprecated.h
deleted file mode 100644
index 281e5a710..000000000
--- a/core/src/tbox/src/tbox/object/deprecated/deprecated.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file deprecated.h
- *
- */
-#ifndef TB_OBJECT_DEPRECATED_H
-#define TB_OBJECT_DEPRECATED_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "null.h"
-#include "data.h"
-#include "date.h"
-#include "array.h"
-#include "string.h"
-#include "number.h"
-#include "boolean.h"
-#include "dictionary.h"
-
-
-#endif
diff --git a/core/src/tbox/src/tbox/object/deprecated/dictionary.h b/core/src/tbox/src/tbox/object/deprecated/dictionary.h
deleted file mode 100644
index 927ab4410..000000000
--- a/core/src/tbox/src/tbox/object/deprecated/dictionary.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file dictionary.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_DEPRECATED_DICTIONARY_H
-#define TB_OBJECT_DEPRECATED_DICTIONARY_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-#define TB_OBJECT_DICTIONARY_SIZE_MICRO (64)
-#define TB_OBJECT_DICTIONARY_SIZE_SMALL (256)
-#define TB_OBJECT_DICTIONARY_SIZE_LARGE (65536)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the dictionary item type
-typedef struct __tb_object_dictionary_item_t
-{
- /// the key
- tb_char_t const* key;
-
- /// the value
- tb_object_ref_t val;
-
-}tb_object_dictionary_item_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-#define tb_object_dictionary_init tb_oc_dictionary_init
-#define tb_object_dictionary_size tb_oc_dictionary_size
-#define tb_object_dictionary_incr tb_oc_dictionary_incr
-#define tb_object_dictionary_itor tb_oc_dictionary_itor
-#define tb_object_dictionary_value tb_oc_dictionary_value
-#define tb_object_dictionary_insert tb_oc_dictionary_insert
-#define tb_object_dictionary_remove tb_oc_dictionary_remove
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/deprecated/null.h b/core/src/tbox/src/tbox/object/deprecated/null.h
deleted file mode 100644
index bd4eb3d5d..000000000
--- a/core/src/tbox/src/tbox/object/deprecated/null.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file null.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_DEPRECATED_NULL_H
-#define TB_OBJECT_DEPRECATED_NULL_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-#define tb_object_null_init tb_oc_null_init
-
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/deprecated/number.h b/core/src/tbox/src/tbox/object/deprecated/number.h
deleted file mode 100644
index 87e140ecd..000000000
--- a/core/src/tbox/src/tbox/object/deprecated/number.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file number.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_DEPRECATED_NUMBER_H
-#define TB_OBJECT_DEPRECATED_NUMBER_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the number type enum
-typedef enum __tb_object_number_type_e
-{
- TB_NUMBER_TYPE_NONE = 0
-, TB_NUMBER_TYPE_UINT8 = 1
-, TB_NUMBER_TYPE_SINT8 = 2
-, TB_NUMBER_TYPE_UINT16 = 3
-, TB_NUMBER_TYPE_SINT16 = 4
-, TB_NUMBER_TYPE_UINT32 = 5
-, TB_NUMBER_TYPE_SINT32 = 6
-, TB_NUMBER_TYPE_UINT64 = 7
-, TB_NUMBER_TYPE_SINT64 = 8
-, TB_NUMBER_TYPE_FLOAT = 9
-, TB_NUMBER_TYPE_DOUBLE = 10
-
-}tb_object_number_type_e;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-#define tb_object_number_init_from_uint8 tb_oc_number_init_from_uint8
-#define tb_object_number_init_from_sint8 tb_oc_number_init_from_sint8
-#define tb_object_number_init_from_uint16 tb_oc_number_init_from_uint16
-#define tb_object_number_init_from_sint16 tb_oc_number_init_from_sint16
-#define tb_object_number_init_from_uint32 tb_oc_number_init_from_uint32
-#define tb_object_number_init_from_sint32 tb_oc_number_init_from_sint32
-#define tb_object_number_init_from_uint64 tb_oc_number_init_from_uint64
-#define tb_object_number_init_from_sint64 tb_oc_number_init_from_sint64
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
-# define tb_object_number_init_from_float tb_oc_number_init_from_float
-# define tb_object_number_init_from_double tb_oc_number_init_from_double
-#endif
-
-#define tb_object_number_type tb_oc_number_type
-#define tb_object_number_uint8 tb_oc_number_uint8
-#define tb_object_number_sint8 tb_oc_number_sint8
-#define tb_object_number_uint16 tb_oc_number_uint16
-#define tb_object_number_sint16 tb_oc_number_sint16
-#define tb_object_number_uint32 tb_oc_number_uint32
-#define tb_object_number_sint32 tb_oc_number_sint32
-#define tb_object_number_uint64 tb_oc_number_uint64
-#define tb_object_number_sint64 tb_oc_number_sint64
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
-# define tb_object_number_float tb_oc_number_float
-# define tb_object_number_double tb_oc_number_double
-#endif
-
-#define tb_object_number_uint8_set tb_oc_number_uint8_set
-#define tb_object_number_sint8_set tb_oc_number_sint8_set
-#define tb_object_number_uint16_set tb_oc_number_uint16_set
-#define tb_object_number_sint16_set tb_oc_number_sint16_set
-#define tb_object_number_uint32_set tb_oc_number_uint32_set
-#define tb_object_number_sint32_set tb_oc_number_sint32_set
-#define tb_object_number_uint64_set tb_oc_number_uint64_set
-#define tb_object_number_sint64_set tb_oc_number_sint64_set
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
-# define tb_object_number_floa_set tb_oc_number_float_set
-# define tb_object_number_double_set tb_oc_number_double_set
-#endif
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/deprecated/prefix.h b/core/src/tbox/src/tbox/object/deprecated/prefix.h
deleted file mode 100644
index 80098707e..000000000
--- a/core/src/tbox/src/tbox/object/deprecated/prefix.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file prefix.h
- *
- */
-#ifndef TB_OBJECT_DEPRECATED_PREFIX_H
-#define TB_OBJECT_DEPRECATED_PREFIX_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "../prefix.h"
-
-
-
-#endif
diff --git a/core/src/tbox/src/tbox/object/deprecated/string.h b/core/src/tbox/src/tbox/object/deprecated/string.h
deleted file mode 100644
index d4f6d7659..000000000
--- a/core/src/tbox/src/tbox/object/deprecated/string.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file string.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_DEPRECATED_STRING_H
-#define TB_OBJECT_DEPRECATED_STRING_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-#define tb_object_string_init_from_cstr tb_oc_string_init_from_cstr
-#define tb_object_string_init_from_str tb_oc_string_init_from_str
-#define tb_object_string_cstr tb_oc_string_cstr
-#define tb_object_string_cstr_set tb_oc_string_cstr_set
-#define tb_object_string_size tb_oc_string_size
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/dictionary.c b/core/src/tbox/src/tbox/object/dictionary.c
deleted file mode 100644
index 9e784a697..000000000
--- a/core/src/tbox/src/tbox/object/dictionary.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file dictionary.c
- * @ingroup object
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "oc_dictionary"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "object.h"
-#include "../string/string.h"
-#include "../algorithm/algorithm.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-#ifdef __tb_small__
-# define TB_OC_DICTIONARY_SIZE_DEFAULT TB_OC_DICTIONARY_SIZE_MICRO
-#else
-# define TB_OC_DICTIONARY_SIZE_DEFAULT TB_OC_DICTIONARY_SIZE_SMALL
-#endif
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the dictionary type
-typedef struct __tb_oc_dictionary_t
-{
- // the object base
- tb_object_t base;
-
- // the capacity size
- tb_size_t size;
-
- // the object hash
- tb_hash_map_ref_t hash;
-
- // increase refn?
- tb_bool_t incr;
-
-}tb_oc_dictionary_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static __tb_inline__ tb_oc_dictionary_t* tb_oc_dictionary_cast(tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return_val(object && object->type == TB_OBJECT_TYPE_DICTIONARY, tb_null);
-
- // cast
- return (tb_oc_dictionary_t*)object;
-}
-static tb_object_ref_t tb_oc_dictionary_copy(tb_object_ref_t object)
-{
- // check
- tb_oc_dictionary_t* dictionary = tb_oc_dictionary_cast(object);
- tb_assert_and_check_return_val(dictionary, tb_null);
-
- // init copy
- tb_oc_dictionary_t* copy = (tb_oc_dictionary_t*)tb_oc_dictionary_init(dictionary->size, dictionary->incr);
- tb_assert_and_check_return_val(copy, tb_null);
-
- // walk copy
- tb_for_all (tb_oc_dictionary_item_t*, item, tb_oc_dictionary_itor((tb_object_ref_t)dictionary))
- {
- if (item && item->key)
- {
- // refn++
- if (item->val) tb_object_retain(item->val);
-
- // copy
- tb_oc_dictionary_insert((tb_object_ref_t)copy, item->key, item->val);
- }
- }
-
- // ok
- return (tb_object_ref_t)copy;
-}
-static tb_void_t tb_oc_dictionary_exit(tb_object_ref_t object)
-{
- // check
- tb_oc_dictionary_t* dictionary = tb_oc_dictionary_cast(object);
- tb_assert_and_check_return(dictionary);
-
- // exit hash
- if (dictionary->hash) tb_hash_map_exit(dictionary->hash);
- dictionary->hash = tb_null;
-
- // exit it
- tb_free(dictionary);
-}
-static tb_void_t tb_oc_dictionary_clear(tb_object_ref_t object)
-{
- tb_oc_dictionary_t* dictionary = tb_oc_dictionary_cast(object);
- tb_assert_and_check_return(dictionary);
-
- // clear
- if (dictionary->hash) tb_hash_map_clear(dictionary->hash);
-}
-static tb_oc_dictionary_t* tb_oc_dictionary_init_base()
-{
- // done
- tb_bool_t ok = tb_false;
- tb_oc_dictionary_t* dictionary = tb_null;
- do
- {
- // make dictionary
- dictionary = tb_malloc0_type(tb_oc_dictionary_t);
- tb_assert_and_check_break(dictionary);
-
- // init dictionary
- if (!tb_object_init((tb_object_ref_t)dictionary, TB_OBJECT_FLAG_NONE, TB_OBJECT_TYPE_DICTIONARY)) break;
-
- // init base
- dictionary->base.copy = tb_oc_dictionary_copy;
- dictionary->base.exit = tb_oc_dictionary_exit;
- dictionary->base.clear = tb_oc_dictionary_clear;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (dictionary) tb_object_exit((tb_object_ref_t)dictionary);
- dictionary = tb_null;
- }
-
- // ok?
- return dictionary;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-tb_object_ref_t tb_oc_dictionary_init(tb_size_t size, tb_bool_t incr)
-{
- // done
- tb_bool_t ok = tb_false;
- tb_oc_dictionary_t* dictionary = tb_null;
- do
- {
- // make dictionary
- dictionary = tb_oc_dictionary_init_base();
- tb_assert_and_check_break(dictionary);
-
- // using the default size
- if (!size) size = TB_OC_DICTIONARY_SIZE_DEFAULT;
-
- // init
- dictionary->size = size;
- dictionary->incr = incr;
-
- // init hash
- dictionary->hash = tb_hash_map_init(size, tb_element_str(tb_true), tb_element_obj());
- tb_assert_and_check_break(dictionary->hash);
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (dictionary) tb_oc_dictionary_exit((tb_object_ref_t)dictionary);
- dictionary = tb_null;
- }
-
- // ok?
- return (tb_object_ref_t)dictionary;
-}
-tb_size_t tb_oc_dictionary_size(tb_object_ref_t object)
-{
- // check
- tb_oc_dictionary_t* dictionary = tb_oc_dictionary_cast(object);
- tb_assert_and_check_return_val(dictionary && dictionary->hash, 0);
-
- // size
- return tb_hash_map_size(dictionary->hash);
-}
-tb_iterator_ref_t tb_oc_dictionary_itor(tb_object_ref_t object)
-{
- tb_oc_dictionary_t* dictionary = tb_oc_dictionary_cast(object);
- tb_assert_and_check_return_val(dictionary, tb_null);
-
- // iterator
- return (tb_iterator_ref_t)dictionary->hash;
-}
-tb_object_ref_t tb_oc_dictionary_value(tb_object_ref_t object, tb_char_t const* key)
-{
- // check
- tb_oc_dictionary_t* dictionary = tb_oc_dictionary_cast(object);
- tb_assert_and_check_return_val(dictionary && dictionary->hash && key, tb_null);
-
- // value
- return (tb_object_ref_t)tb_hash_map_get(dictionary->hash, key);
-}
-tb_void_t tb_oc_dictionary_remove(tb_object_ref_t object, tb_char_t const* key)
-{
- // check
- tb_oc_dictionary_t* dictionary = tb_oc_dictionary_cast(object);
- tb_assert_and_check_return(dictionary && dictionary->hash && key);
-
- // del
- return tb_hash_map_remove(dictionary->hash, key);
-}
-tb_void_t tb_oc_dictionary_insert(tb_object_ref_t object, tb_char_t const* key, tb_object_ref_t val)
-{
- // check
- tb_oc_dictionary_t* dictionary = tb_oc_dictionary_cast(object);
- tb_assert_and_check_return(dictionary && dictionary->hash && key && val);
-
- // add
- tb_hash_map_insert(dictionary->hash, key, val);
-
- // refn--
- if (!dictionary->incr) tb_object_exit(val);
-}
-tb_void_t tb_oc_dictionary_incr(tb_object_ref_t object, tb_bool_t incr)
-{
- // check
- tb_oc_dictionary_t* dictionary = tb_oc_dictionary_cast(object);
- tb_assert_and_check_return(dictionary);
-
- dictionary->incr = incr;
-}
diff --git a/core/src/tbox/src/tbox/object/dictionary.h b/core/src/tbox/src/tbox/object/dictionary.h
deleted file mode 100644
index 67a144ed2..000000000
--- a/core/src/tbox/src/tbox/object/dictionary.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file dictionary.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_DICTIONARY_H
-#define TB_OBJECT_DICTIONARY_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-#define TB_OC_DICTIONARY_SIZE_MICRO (64)
-#define TB_OC_DICTIONARY_SIZE_SMALL (256)
-#define TB_OC_DICTIONARY_SIZE_LARGE (65536)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the dictionary item type
-typedef struct __tb_oc_dictionary_item_t
-{
- /// the key
- tb_char_t const* key;
-
- /// the value
- tb_object_ref_t val;
-
-}tb_oc_dictionary_item_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init dictionary
- *
- * @code
- // init dictionary
- // {"key1": "hello", "key2" :"world", "key3": 12345, "key4": true}
- tb_object_ref_t dict = tb_oc_dictionary_init(0, tb_false);
- if (dict)
- {
- // key1 => hello
- tb_oc_dictionary_insert(dict, "key1", tb_oc_string_init_from_cstr("hello"));
-
- // key2 => world
- tb_oc_dictionary_insert(dict, "key2", tb_oc_string_init_from_cstr("world"));
-
- // key3 => 12345
- tb_oc_dictionary_insert(dict, "key3", tb_oc_number_init_from_sint32(12345));
-
- // key4 => true
- tb_oc_dictionary_insert(dict, "key4", tb_oc_boolean_true());
-
- // exit dictionary
- tb_object_exit(dict);
- }
- * @endcode
- *
- * @param size the dictionary size, using the default size if be zero
- * @param incr is increase refn?
- *
- * @return the dictionary object
- */
-tb_object_ref_t tb_oc_dictionary_init(tb_size_t size, tb_bool_t incr);
-
-/*! the dictionary size
- *
- * @param dictionary the dictionary object
- *
- * @return the dictionary size
- */
-tb_size_t tb_oc_dictionary_size(tb_object_ref_t dictionary);
-
-/*! set the dictionary incr
- *
- * @param dictionary the dictionary object
- * @param incr is increase refn?
- */
-tb_void_t tb_oc_dictionary_incr(tb_object_ref_t dictionary, tb_bool_t incr);
-
-/*! the dictionary iterator
- *
- * @param dictionary the dictionary object
- *
- * @return the dictionary iterator
- *
- * @code
- tb_for_all (tb_oc_dictionary_item_t*, item, tb_oc_dictionary_itor(dictionary))
- {
- if (item)
- {
- tb_char_t const* key = item->key;
- tb_object_ref_t val = item->val;
-
- // ...
- }
- }
- * @endcode
- */
-tb_iterator_ref_t tb_oc_dictionary_itor(tb_object_ref_t dictionary);
-
-/*! get the dictionary value
- *
- * @param dictionary the dictionary object
- * @param key the key
- *
- * @return the dictionary value
- */
-tb_object_ref_t tb_oc_dictionary_value(tb_object_ref_t dictionary, tb_char_t const* key);
-
-/*! insert dictionary item
- *
- * @param dictionary the dictionary object
- * @param key the key
- * @param val the value
- */
-tb_void_t tb_oc_dictionary_insert(tb_object_ref_t dictionary, tb_char_t const* key, tb_object_ref_t val);
-
-/*! remove dictionary item
- *
- * @param dictionary the dictionary object
- * @param key the key
- */
-tb_void_t tb_oc_dictionary_remove(tb_object_ref_t dictionary, tb_char_t const* key);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/impl/impl.h b/core/src/tbox/src/tbox/object/impl/impl.h
deleted file mode 100644
index ad484e737..000000000
--- a/core/src/tbox/src/tbox/object/impl/impl.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file impl.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_IMPL_H
-#define TB_OBJECT_IMPL_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "object.h"
-#include "reader/reader.h"
-#include "writer/writer.h"
-
-#endif
diff --git a/core/src/tbox/src/tbox/object/impl/object.c b/core/src/tbox/src/tbox/object/impl/object.c
deleted file mode 100644
index d73bcf194..000000000
--- a/core/src/tbox/src/tbox/object/impl/object.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file object.c
- * @ingroup object
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "object"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "object.h"
-#include "reader/reader.h"
-#include "writer/writer.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_bool_t tb_object_init_env()
-{
- // register reader
- if (!tb_oc_reader_set(TB_OBJECT_FORMAT_BIN, tb_oc_bin_reader())) return tb_false;
- if (!tb_oc_reader_set(TB_OBJECT_FORMAT_JSON, tb_oc_json_reader())) return tb_false;
- if (!tb_oc_reader_set(TB_OBJECT_FORMAT_BPLIST, tb_oc_bplist_reader())) return tb_false;
-
- // register writer
- if (!tb_oc_writer_set(TB_OBJECT_FORMAT_BIN, tb_oc_bin_writer())) return tb_false;
- if (!tb_oc_writer_set(TB_OBJECT_FORMAT_JSON, tb_oc_json_writer())) return tb_false;
- if (!tb_oc_writer_set(TB_OBJECT_FORMAT_BPLIST, tb_oc_bplist_writer())) return tb_false;
-
- // register reader and writer for xml
-#ifdef TB_CONFIG_MODULE_HAVE_XML
- if (!tb_oc_reader_set(TB_OBJECT_FORMAT_XML, tb_oc_xml_reader())) return tb_false;
- if (!tb_oc_writer_set(TB_OBJECT_FORMAT_XML, tb_oc_xml_writer())) return tb_false;
- if (!tb_oc_reader_set(TB_OBJECT_FORMAT_XPLIST, tb_oc_xplist_reader())) return tb_false;
- if (!tb_oc_writer_set(TB_OBJECT_FORMAT_XPLIST, tb_oc_xplist_writer())) return tb_false;
-#endif
-
- // ok
- return tb_true;
-}
-tb_void_t tb_object_exit_env()
-{
- // remove reader
- tb_oc_reader_remove(TB_OBJECT_FORMAT_BIN);
- tb_oc_reader_remove(TB_OBJECT_FORMAT_JSON);
- tb_oc_reader_remove(TB_OBJECT_FORMAT_BPLIST);
-
- // remove writer
- tb_oc_writer_remove(TB_OBJECT_FORMAT_BIN);
- tb_oc_writer_remove(TB_OBJECT_FORMAT_JSON);
- tb_oc_writer_remove(TB_OBJECT_FORMAT_BPLIST);
-
- // remove reader and writer for xml
-#ifdef TB_CONFIG_MODULE_HAVE_XML
- tb_oc_reader_remove(TB_OBJECT_FORMAT_XML);
- tb_oc_writer_remove(TB_OBJECT_FORMAT_XML);
- tb_oc_reader_remove(TB_OBJECT_FORMAT_XPLIST);
- tb_oc_writer_remove(TB_OBJECT_FORMAT_XPLIST);
-#endif
-}
-
diff --git a/core/src/tbox/src/tbox/object/impl/object.h b/core/src/tbox/src/tbox/object/impl/object.h
deleted file mode 100644
index 500b19a73..000000000
--- a/core/src/tbox/src/tbox/object/impl/object.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file object.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_IMPL_OBJECT_H
-#define TB_OBJECT_IMPL_OBJECT_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/* init object envirnoment
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_object_init_env(tb_noarg_t);
-
-// exit object envirnoment
-tb_void_t tb_object_exit_env(tb_noarg_t);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/impl/prefix.h b/core/src/tbox/src/tbox/object/impl/prefix.h
deleted file mode 100644
index ecdfdb27d..000000000
--- a/core/src/tbox/src/tbox/object/impl/prefix.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file prefix.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_IMPL_PREFIX_H
-#define TB_OBJECT_IMPL_PREFIX_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "../prefix.h"
-#include "../object.h"
-#include "../../stream/stream.h"
-#include "../../charset/charset.h"
-#include "../../container/container.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-// need bytes
-#define tb_object_need_bytes(x) \
- (((tb_uint64_t)(x)) < (1ull << 8) ? 1 : \
- (((tb_uint64_t)(x)) < (1ull << 16) ? 2 : \
- (((tb_uint64_t)(x)) < (1ull << 32) ? 4 : 8)))
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the object reader type
-typedef struct __tb_oc_reader_t
-{
- /// the hooker
- tb_hash_map_ref_t hooker;
-
- /// probe format
- tb_size_t (*probe)(tb_stream_ref_t stream);
-
- /// read it
- tb_object_ref_t (*read)(tb_stream_ref_t stream);
-
-}tb_oc_reader_t;
-
-// the object writer type
-typedef struct __tb_oc_writer_t
-{
- /// the hooker
- tb_hash_map_ref_t hooker;
-
- /// writ it
- tb_long_t (*writ)(tb_stream_ref_t stream, tb_object_ref_t object, tb_bool_t deflate);
-
-}tb_oc_writer_t;
-
-#endif
diff --git a/core/src/tbox/src/tbox/object/impl/reader/bin.c b/core/src/tbox/src/tbox/object/impl/reader/bin.c
deleted file mode 100644
index 66a78d832..000000000
--- a/core/src/tbox/src/tbox/object/impl/reader/bin.c
+++ /dev/null
@@ -1,550 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file bin.c
- * @ingroup object
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "oc_reader_bin"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "bin.h"
-#include "reader.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-// the array grow
-#ifdef __tb_small__
-# define TB_OC_BIN_READER_ARRAY_GROW (64)
-#else
-# define TB_OC_BIN_READER_ARRAY_GROW (256)
-#endif
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static tb_object_ref_t tb_oc_bin_reader_func_null(tb_oc_bin_reader_t* reader, tb_size_t type, tb_uint64_t size)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream && reader->list, tb_null);
-
- // ok
- return tb_oc_null_init();
-}
-static tb_object_ref_t tb_oc_bin_reader_func_date(tb_oc_bin_reader_t* reader, tb_size_t type, tb_uint64_t size)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream && reader->list, tb_null);
-
- // ok
- return tb_oc_date_init_from_time((tb_time_t)size);
-}
-static tb_object_ref_t tb_oc_bin_reader_func_data(tb_oc_bin_reader_t* reader, tb_size_t type, tb_uint64_t size)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream && reader->list, tb_null);
-
- // empty?
- if (!size) return tb_oc_data_init_from_data(tb_null, 0);
-
- // make data
- tb_char_t* data = tb_malloc0_cstr((tb_size_t)size);
- tb_assert_and_check_return_val(data, tb_null);
-
- // read data
- if (!tb_stream_bread(reader->stream, (tb_byte_t*)data, (tb_size_t)size))
- {
- tb_free(data);
- return tb_null;
- }
-
- // decode data
- {
- tb_byte_t* pb = (tb_byte_t*)data;
- tb_byte_t* pe = (tb_byte_t*)data + size;
- tb_byte_t xb = (tb_byte_t)(((size >> 8) & 0xff) | (size & 0xff));
- for (; pb < pe; pb++, xb++) *pb ^= xb;
- }
-
- // make the data object
- tb_object_ref_t object = tb_oc_data_init_from_data(data, (tb_size_t)size);
-
- // exit data
- tb_free(data);
-
- // ok?
- return object;
-}
-static tb_object_ref_t tb_oc_bin_reader_func_array(tb_oc_bin_reader_t* reader, tb_size_t type, tb_uint64_t size)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream && reader->list, tb_null);
-
- // empty?
- if (!size) return tb_oc_array_init(TB_OC_BIN_READER_ARRAY_GROW, tb_false);
-
- // init array
- tb_object_ref_t array = tb_oc_array_init(TB_OC_BIN_READER_ARRAY_GROW, tb_false);
- tb_assert_and_check_return_val(array, tb_null);
-
- // walk
- tb_size_t i = 0;
- tb_size_t n = (tb_size_t)size;
- for (i = 0; i < n; i++)
- {
- // the type & size
- tb_size_t type = 0;
- tb_uint64_t size = 0;
- tb_oc_reader_bin_type_size(reader->stream, &type, &size);
-
- // trace
- tb_trace_d("item: type: %lu, size: %llu", type, size);
-
- // is index?
- tb_object_ref_t item = tb_null;
- if (!type)
- {
- // the object index
- tb_size_t index = (tb_size_t)size;
-
- // check
- tb_assert_and_check_break(index < tb_vector_size(reader->list));
-
- // the item
- item = (tb_object_ref_t)tb_iterator_item(reader->list, index);
-
- // refn++
- if (item) tb_object_retain(item);
- }
- else
- {
- // the reader func
- tb_oc_bin_reader_func_t func = tb_oc_bin_reader_func(type);
- tb_assert_and_check_break(func);
-
- // read it
- item = func(reader, type, size);
-
- // save it
- tb_vector_insert_tail(reader->list, item);
- }
-
- // check
- tb_assert_and_check_break(item);
-
- // append item
- tb_oc_array_append(array, item);
- }
-
- // failed?
- if (i != n)
- {
- if (array) tb_object_exit(array);
- array = tb_null;
- }
-
- // ok?
- return array;
-}
-static tb_object_ref_t tb_oc_bin_reader_func_string(tb_oc_bin_reader_t* reader, tb_size_t type, tb_uint64_t size)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream && reader->list, tb_null);
-
- // empty?
- if (!size) return tb_oc_string_init_from_cstr(tb_null);
-
- // make data
- tb_char_t* data = tb_malloc0_cstr((tb_size_t)size + 1);
- tb_assert_and_check_return_val(data, tb_null);
-
- // read data
- if (!tb_stream_bread(reader->stream, (tb_byte_t*)data, (tb_size_t)size))
- {
- tb_free(data);
- return tb_null;
- }
-
- // decode string
- {
- tb_byte_t* pb = (tb_byte_t*)data;
- tb_byte_t* pe = (tb_byte_t*)data + size;
- tb_byte_t xb = (tb_byte_t)(((size >> 8) & 0xff) | (size & 0xff));
- for (; pb < pe; pb++, xb++) *pb ^= xb;
- }
-
- // make string
- tb_object_ref_t string = tb_oc_string_init_from_cstr(data);
-
- // exit data
- tb_free(data);
-
- // ok?
- return string;
-}
-static tb_object_ref_t tb_oc_bin_reader_func_number(tb_oc_bin_reader_t* reader, tb_size_t type, tb_uint64_t size)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream && reader->list, tb_null);
-
- // the number type
- tb_size_t number_type = (tb_size_t)size;
-
- // read number
- tb_value_t value;
- tb_object_ref_t number = tb_null;
- switch (number_type)
- {
- case TB_OC_NUMBER_TYPE_UINT64:
- {
- // read and init number
- if (tb_stream_bread_u64_be(reader->stream, &value.u64))
- number = tb_oc_number_init_from_uint64(value.u64);
- }
- break;
- case TB_OC_NUMBER_TYPE_SINT64:
- {
- // read and init number
- if (tb_stream_bread_s64_be(reader->stream, &value.s64))
- number = tb_oc_number_init_from_sint64(value.s64);
- }
- break;
- case TB_OC_NUMBER_TYPE_UINT32:
- {
- // read and init number
- if (tb_stream_bread_u32_be(reader->stream, &value.u32))
- number = tb_oc_number_init_from_uint32(value.u32);
- }
- break;
- case TB_OC_NUMBER_TYPE_SINT32:
- {
- // read and init number
- if (tb_stream_bread_s32_be(reader->stream, &value.s32))
- number = tb_oc_number_init_from_sint32(value.s32);
- }
- break;
- case TB_OC_NUMBER_TYPE_UINT16:
- {
- // read and init number
- if (tb_stream_bread_u16_be(reader->stream, &value.u16))
- number = tb_oc_number_init_from_uint16(value.u16);
- }
- break;
- case TB_OC_NUMBER_TYPE_SINT16:
- {
- // read and init number
- if (tb_stream_bread_s16_be(reader->stream, &value.s16))
- number = tb_oc_number_init_from_sint16(value.s16);
- }
- break;
- case TB_OC_NUMBER_TYPE_UINT8:
- {
- // read and init number
- if (tb_stream_bread_u8(reader->stream, &value.u8))
- number = tb_oc_number_init_from_uint8(value.u8);
- }
- break;
- case TB_OC_NUMBER_TYPE_SINT8:
- {
- // read and init number
- if (tb_stream_bread_s8(reader->stream, &value.s8))
- number = tb_oc_number_init_from_sint8(value.s8);
- }
- break;
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- case TB_OC_NUMBER_TYPE_FLOAT:
- {
- // read and init number
- if (tb_stream_bread_float_be(reader->stream, &value.f))
- number = tb_oc_number_init_from_float(value.f);
- }
- break;
- case TB_OC_NUMBER_TYPE_DOUBLE:
- {
- // read and init number
- if (tb_stream_bread_double_bbe(reader->stream, &value.d))
- number = tb_oc_number_init_from_double(value.d);
- }
- break;
-#endif
- default:
- tb_assert_and_check_return_val(0, tb_null);
- break;
- }
-
- // ok?
- return number;
-}
-static tb_object_ref_t tb_oc_bin_reader_func_boolean(tb_oc_bin_reader_t* reader, tb_size_t type, tb_uint64_t size)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream && reader->list, tb_null);
-
- // ok?
- return tb_oc_boolean_init(size? tb_true : tb_false);
-}
-static tb_object_ref_t tb_oc_bin_reader_func_dictionary(tb_oc_bin_reader_t* reader, tb_size_t type, tb_uint64_t size)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream && reader->list, tb_null);
-
- // empty?
- if (!size) return tb_oc_dictionary_init(TB_OC_DICTIONARY_SIZE_MICRO, tb_false);
-
- // init dictionary
- tb_object_ref_t dictionary = tb_oc_dictionary_init(0, tb_false);
- tb_assert_and_check_return_val(dictionary, tb_null);
-
- // walk
- tb_size_t i = 0;
- tb_size_t n = (tb_size_t)size;
- for (i = 0; i < n; i++)
- {
- // read key
- tb_object_ref_t key = tb_null;
- do
- {
- // the type & size
- tb_size_t type = 0;
- tb_uint64_t size = 0;
- tb_oc_reader_bin_type_size(reader->stream, &type, &size);
-
- // trace
- tb_trace_d("key: type: %lu, size: %llu", type, size);
-
- // is index?
- if (!type)
- {
- // the object index
- tb_size_t index = (tb_size_t)size;
-
- // check
- tb_assert_and_check_break(index < tb_vector_size(reader->list));
-
- // the item
- key = (tb_object_ref_t)tb_iterator_item(reader->list, index);
- }
- else
- {
- // check
- tb_assert_and_check_break(type == TB_OBJECT_TYPE_STRING);
-
- // the reader func
- tb_oc_bin_reader_func_t func = tb_oc_bin_reader_func(type);
- tb_assert_and_check_break(func);
-
- // read it
- key = func(reader, type, size);
- tb_assert_and_check_break(key);
-
- // save it
- tb_vector_insert_tail(reader->list, key);
-
- // refn--
- tb_object_exit(key);
- }
-
- } while (0);
-
- // check
- tb_assert_and_check_break(key && tb_object_type(key) == TB_OBJECT_TYPE_STRING);
- tb_assert_and_check_break(tb_oc_string_size(key) && tb_oc_string_cstr(key));
-
- // read val
- tb_object_ref_t val = tb_null;
- do
- {
- // the type & size
- tb_size_t type = 0;
- tb_uint64_t size = 0;
- tb_oc_reader_bin_type_size(reader->stream, &type, &size);
-
- // trace
- tb_trace_d("val: type: %lu, size: %llu", type, size);
-
- // is index?
- if (!type)
- {
- // the object index
- tb_size_t index = (tb_size_t)size;
-
- // check
- tb_assert_and_check_break(index < tb_vector_size(reader->list));
-
- // the item
- val = (tb_object_ref_t)tb_iterator_item(reader->list, index);
-
- // refn++
- if (val) tb_object_retain(val);
- }
- else
- {
- // the reader func
- tb_oc_bin_reader_func_t func = tb_oc_bin_reader_func(type);
- tb_assert_and_check_break(func);
-
- // read it
- val = func(reader, type, size);
-
- // save it
- if (val) tb_vector_insert_tail(reader->list, val);
- }
-
- } while (0);
-
- // check
- tb_assert_and_check_break(val);
-
- // set key => val
- tb_oc_dictionary_insert(dictionary, tb_oc_string_cstr(key), val);
- }
-
- // failed?
- if (i != n)
- {
- if (dictionary) tb_object_exit(dictionary);
- dictionary = tb_null;
- }
-
- // ok?
- return dictionary;
-}
-static tb_object_ref_t tb_oc_bin_reader_done(tb_stream_ref_t stream)
-{
- // read bin header
- tb_byte_t data[32] = {0};
- if (!tb_stream_bread(stream, data, 5)) return tb_null;
-
- // check
- if (tb_strnicmp((tb_char_t const*)data, "tbo00", 5)) return tb_null;
-
- // init
- tb_object_ref_t object = tb_null;
- tb_oc_bin_reader_t reader = {0};
-
- // init reader
- reader.stream = stream;
- reader.list = tb_vector_init(256, tb_element_obj());
- tb_assert_and_check_return_val(reader.list, tb_null);
-
- // the type & size
- tb_size_t type = 0;
- tb_uint64_t size = 0;
- tb_oc_reader_bin_type_size(stream, &type, &size);
-
- // trace
- tb_trace_d("root: type: %lu, size: %llu", type, size);
-
- // the func
- tb_oc_bin_reader_func_t func = tb_oc_bin_reader_func(type);
-
- // check
- tb_assert(func);
-
- // read it
- if (func) object = func(&reader, type, size);
-
- // exit the list
- if (reader.list) tb_vector_exit(reader.list);
-
- // ok?
- return object;
-}
-static tb_size_t tb_oc_bin_reader_probe(tb_stream_ref_t stream)
-{
- // check
- tb_assert_and_check_return_val(stream, 0);
-
- // need it
- tb_byte_t* p = tb_null;
- if (!tb_stream_need(stream, &p, 3)) return 0;
- tb_assert_and_check_return_val(p, 0);
-
- // ok?
- return !tb_strnicmp((tb_char_t const*)p, "tbo", 3)? 80 : 0;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-tb_oc_reader_t* tb_oc_bin_reader()
-{
- // the reader
- static tb_oc_reader_t s_reader = {0};
-
- // init reader
- s_reader.read = tb_oc_bin_reader_done;
- s_reader.probe = tb_oc_bin_reader_probe;
-
- // init hooker
- s_reader.hooker = tb_hash_map_init(TB_HASH_MAP_BUCKET_SIZE_MICRO, tb_element_uint32(), tb_element_ptr(tb_null, tb_null));
- tb_assert_and_check_return_val(s_reader.hooker, tb_null);
-
- // hook reader
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)TB_OBJECT_TYPE_NULL, tb_oc_bin_reader_func_null);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)TB_OBJECT_TYPE_DATE, tb_oc_bin_reader_func_date);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)TB_OBJECT_TYPE_DATA, tb_oc_bin_reader_func_data);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)TB_OBJECT_TYPE_ARRAY, tb_oc_bin_reader_func_array);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)TB_OBJECT_TYPE_STRING, tb_oc_bin_reader_func_string);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)TB_OBJECT_TYPE_NUMBER, tb_oc_bin_reader_func_number);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)TB_OBJECT_TYPE_BOOLEAN, tb_oc_bin_reader_func_boolean);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)TB_OBJECT_TYPE_DICTIONARY, tb_oc_bin_reader_func_dictionary);
-
- // ok
- return &s_reader;
-}
-tb_bool_t tb_oc_bin_reader_hook(tb_size_t type, tb_oc_bin_reader_func_t func)
-{
- // check
- tb_assert_and_check_return_val(type && func, tb_false);
-
- // the reader
- tb_oc_reader_t* reader = tb_oc_reader_get(TB_OBJECT_FORMAT_BIN);
- tb_assert_and_check_return_val(reader && reader->hooker, tb_false);
-
- // hook it
- tb_hash_map_insert(reader->hooker, (tb_pointer_t)type, func);
-
- // ok
- return tb_true;
-}
-tb_oc_bin_reader_func_t tb_oc_bin_reader_func(tb_size_t type)
-{
- // check
- tb_assert_and_check_return_val(type, tb_null);
-
- // the reader
- tb_oc_reader_t* reader = tb_oc_reader_get(TB_OBJECT_FORMAT_BIN);
- tb_assert_and_check_return_val(reader && reader->hooker, tb_null);
-
- // the func
- return (tb_oc_bin_reader_func_t)tb_hash_map_get(reader->hooker, (tb_pointer_t)type);
-}
-
diff --git a/core/src/tbox/src/tbox/object/impl/reader/bin.h b/core/src/tbox/src/tbox/object/impl/reader/bin.h
deleted file mode 100644
index 900bde20a..000000000
--- a/core/src/tbox/src/tbox/object/impl/reader/bin.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file bin.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_IMPL_READER_BIN_H
-#define TB_OBJECT_IMPL_READER_BIN_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the bin reader type
-typedef struct __tb_oc_bin_reader_t
-{
- /// the stream
- tb_stream_ref_t stream;
-
- /// the object list
- tb_vector_ref_t list;
-
-}tb_oc_bin_reader_t;
-
-/// the bin reader func type
-typedef tb_object_ref_t (*tb_oc_bin_reader_func_t)(tb_oc_bin_reader_t* reader, tb_size_t type, tb_uint64_t size);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! the bin reader
- *
- * @return the bin object reader
- */
-tb_oc_reader_t* tb_oc_bin_reader(tb_noarg_t);
-
-/*! hook the bin reader
- *
- * @param type the object type
- * @param func the reader func
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_bin_reader_hook(tb_size_t type, tb_oc_bin_reader_func_t func);
-
-/*! the bin reader func
- *
- * @param type the object type
- *
- * @return the object reader func
- */
-tb_oc_bin_reader_func_t tb_oc_bin_reader_func(tb_size_t type);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/impl/reader/bplist.c b/core/src/tbox/src/tbox/object/impl/reader/bplist.c
deleted file mode 100644
index 6d942cc80..000000000
--- a/core/src/tbox/src/tbox/object/impl/reader/bplist.c
+++ /dev/null
@@ -1,821 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file bplist.c
- * @ingroup object
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "oc_reader_bplist"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "bplist.h"
-#include "reader.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-// the array grow
-#ifdef __tb_small__
-# define TB_OC_BPLIST_READER_ARRAY_GROW (64)
-#else
-# define TB_OC_BPLIST_READER_ARRAY_GROW (256)
-#endif
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the bplist type enum
-typedef enum __tb_oc_bplist_type_e
-{
- TB_OC_BPLIST_TYPE_NONE = 0x00
-, TB_OC_BPLIST_TYPE_FALSE = 0x08
-, TB_OC_BPLIST_TYPE_TRUE = 0x09
-, TB_OC_BPLIST_TYPE_UINT = 0x10
-, TB_OC_BPLIST_TYPE_REAL = 0x20
-, TB_OC_BPLIST_TYPE_DATE = 0x30
-, TB_OC_BPLIST_TYPE_DATA = 0x40
-, TB_OC_BPLIST_TYPE_STRING = 0x50
-, TB_OC_BPLIST_TYPE_UNICODE = 0x60
-, TB_OC_BPLIST_TYPE_UID = 0x80
-, TB_OC_BPLIST_TYPE_ARRAY = 0xA0
-, TB_OC_BPLIST_TYPE_SET = 0xC0
-, TB_OC_BPLIST_TYPE_DICT = 0xD0
-, TB_OC_BPLIST_TYPE_MASK = 0xF0
-
-}tb_oc_bplist_type_e;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static __tb_inline__ tb_time_t tb_oc_bplist_reader_time_apple2host(tb_time_t time)
-{
- tb_tm_t tm = {0};
- if (tb_localtime(time, &tm))
- {
- if (tm.year < 2000) tm.year += 31;
- time = tb_mktime(&tm);
- }
- return time;
-}
-static __tb_inline__ tb_size_t tb_oc_bplist_bits_get(tb_byte_t const* p, tb_size_t n)
-{
- tb_size_t v = 0;
- switch (n)
- {
- case 1: v = tb_bits_get_u8((p)); break;
- case 2: v = tb_bits_get_u16_be((p)); break;
- case 4: v = tb_bits_get_u32_be((p)); break;
- case 8: v = tb_bits_get_u64_be((p)); break;
- default: break;
- }
- return v;
-}
-static tb_object_ref_t tb_oc_bplist_reader_func_object(tb_oc_bplist_reader_t* reader, tb_size_t item_size)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream, tb_null);
-
- // read the object type
- tb_uint8_t type = 0;
- tb_bool_t ok = tb_stream_bread_u8(reader->stream, &type);
- tb_assert_and_check_return_val(ok, tb_null);
-
- // read the object type and size
- tb_uint8_t size = type & 0x0f; type &= 0xf0;
- tb_trace_d("type: %x, size: %x", type, size);
-
- // the func
- tb_oc_bplist_reader_func_t func = tb_oc_bplist_reader_func(type);
- tb_assert_and_check_return_val(func, tb_null);
-
- // read
- return func(reader, type, size, item_size);
-}
-static tb_long_t tb_oc_bplist_reader_func_size(tb_oc_bplist_reader_t* reader, tb_size_t item_size)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream, -1);
-
- // read size
- tb_object_ref_t object = tb_oc_bplist_reader_func_object(reader, item_size);
- tb_assert_and_check_return_val(object, -1);
-
- tb_long_t size = -1;
- if (tb_object_type(object) == TB_OBJECT_TYPE_NUMBER)
- size = tb_oc_number_uint32(object);
-
- // exit
- tb_object_exit(object);
-
- // size
- return size;
-}
-static tb_object_ref_t tb_oc_bplist_reader_func_data(tb_oc_bplist_reader_t* reader, tb_size_t type, tb_size_t size, tb_size_t item_size)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream, tb_null);
-
- // init
- tb_byte_t* data = tb_null;
- tb_object_ref_t object = tb_null;
-
- // size is too large?
- if (size == 0x0f)
- {
- // read size
- tb_long_t val = tb_oc_bplist_reader_func_size(reader, item_size);
- tb_assert_and_check_return_val(val >= 0, tb_null);
- size = (tb_size_t)val;
- }
-
- // no empty?
- if (size)
- {
- // make data
- data = tb_malloc_bytes(size);
- tb_assert_and_check_return_val(data, tb_null);
-
- // read data
- if (tb_stream_bread(reader->stream, data, size))
- object = tb_oc_data_init_from_data(data, size);
- }
- else object = tb_oc_data_init_from_data(tb_null, 0);
-
- // exit
- if (data) tb_free(data);
-
- // ok?
- return object;
-}
-static tb_object_ref_t tb_oc_bplist_reader_func_array(tb_oc_bplist_reader_t* reader, tb_size_t type, tb_size_t size, tb_size_t item_size)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream, tb_null);
-
- // init
- tb_object_ref_t object = tb_null;
-
- // size is too large?
- if (size == 0x0f)
- {
- // read size
- tb_long_t val = tb_oc_bplist_reader_func_size(reader, item_size);
- tb_assert_and_check_return_val(val >= 0, tb_null);
- size = (tb_size_t)val;
- }
-
- // init array
- object = tb_oc_array_init(size? size : 16, tb_false);
- tb_assert_and_check_return_val(object, tb_null);
-
- // init items data
- if (size)
- {
- tb_byte_t* data = tb_malloc_bytes(sizeof(tb_uint32_t) + (size * item_size));
- if (data)
- {
- if (tb_stream_bread(reader->stream, data + sizeof(tb_uint32_t), size * item_size))
- {
- tb_bits_set_u32_ne(data, (tb_uint32_t)size);
-
- // FIXME: not using the user private data
- tb_object_setp(object, data);
- }
- else tb_free(data);
- }
- }
-
- // ok?
- return object;
-}
-static tb_object_ref_t tb_oc_bplist_reader_func_string(tb_oc_bplist_reader_t* reader, tb_size_t type, tb_size_t size, tb_size_t item_size)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream, tb_null);
-
- // init
- tb_char_t* utf8 = tb_null;
- tb_char_t* utf16 = tb_null;
- tb_object_ref_t object = tb_null;
-
- // read
- switch (type)
- {
- case TB_OC_BPLIST_TYPE_STRING:
- {
- // size is too large?
- if (size == 0x0f)
- {
- // read size
- tb_long_t val = tb_oc_bplist_reader_func_size(reader, item_size);
- tb_assert_and_check_return_val(val >= 0, tb_null);
- size = (tb_size_t)val;
- }
-
- // read string
- if (size)
- {
- // init utf8
- utf8 = tb_malloc_cstr(size + 1);
- tb_assert_and_check_break(utf8);
-
- // read utf8
- if (!tb_stream_bread(reader->stream, (tb_byte_t*)utf8, size)) break;
- utf8[size] = '\0';
- }
-
- // init object
- object = tb_oc_string_init_from_cstr(utf8);
- }
- break;
- case TB_OC_BPLIST_TYPE_UNICODE:
- {
-#ifdef TB_CONFIG_MODULE_HAVE_CHARSET
- // size is too large?
- if (size == 0x0f)
- {
- // read size
- tb_long_t val = tb_oc_bplist_reader_func_size(reader, item_size);
- tb_assert_and_check_return_val(val >= 0, tb_null);
- size = (tb_size_t)val;
- }
-
- // read string
- if (size)
- {
- // init utf8 & utf16 data
- utf8 = tb_malloc_cstr((size + 1) << 2);
- utf16 = tb_malloc_cstr(size << 1);
- tb_assert_and_check_break(utf8 && utf16);
-
- // read utf16
- if (!tb_stream_bread(reader->stream, (tb_byte_t*)utf16, size << 1)) break;
-
- // utf16 to utf8
- tb_long_t osize = tb_charset_conv_data(TB_CHARSET_TYPE_UTF16, TB_CHARSET_TYPE_UTF8, (tb_byte_t*)utf16, size << 1, (tb_byte_t*)utf8, (size + 1) << 2);
- tb_assert_and_check_break(osize > 0 && osize < (tb_long_t)((size + 1) << 2));
- utf8[osize] = '\0';
-
- // init object
- object = tb_oc_string_init_from_cstr(utf8);
- }
-#else
- // trace
- tb_trace1_e("unicode type is not supported, please enable charset module config if you want to use it!");
-#endif
- }
- break;
- default:
- break;
- }
-
- // exit
- if (utf8) tb_free(utf8);
- if (utf16) tb_free(utf16);
-
- // ok?
- return object;
-}
-static tb_object_ref_t tb_oc_bplist_reader_func_number(tb_oc_bplist_reader_t* reader, tb_size_t type, tb_size_t size, tb_size_t item_size)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream, tb_null);
-
- // adjust size
- size = (tb_size_t)1 << size;
-
- // done
- tb_value_t value;
- tb_object_ref_t object = tb_null;
- switch (size)
- {
- case 1:
- {
- // read and init object
- if (tb_stream_bread_u8(reader->stream, &value.u8))
- object = tb_oc_number_init_from_uint8(value.u8);
- }
- break;
- case 2:
- {
- // read and init object
- if (tb_stream_bread_u16_be(reader->stream, &value.u16))
- object = tb_oc_number_init_from_uint16(value.u16);
- }
- break;
- case 4:
- {
- switch (type)
- {
- case TB_OC_BPLIST_TYPE_UID:
- case TB_OC_BPLIST_TYPE_UINT:
- {
- // read and init object
- if (tb_stream_bread_u32_be(reader->stream, &value.u32))
- object = tb_oc_number_init_from_uint32(value.u32);
- }
- break;
- case TB_OC_BPLIST_TYPE_REAL:
- {
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- // read and init object
- if (tb_stream_bread_float_be(reader->stream, &value.f))
- object = tb_oc_number_init_from_float(value.f);
-#else
- tb_trace_e("real type is not supported! please enable float config.");
-#endif
- }
- break;
- default:
- tb_assert(0);
- break;
- }
- }
- break;
- case 8:
- {
- switch (type)
- {
- case TB_OC_BPLIST_TYPE_UID:
- case TB_OC_BPLIST_TYPE_UINT:
- {
- // read and init object
- if (tb_stream_bread_u64_be(reader->stream, &value.u64))
- object = tb_oc_number_init_from_uint64(value.u64);
- }
- break;
- case TB_OC_BPLIST_TYPE_REAL:
- {
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- // read and init object
- if (tb_stream_bread_double_bbe(reader->stream, &value.d))
- object = tb_oc_number_init_from_double(value.d);
-#else
- tb_trace_e("real type is not supported! please enable float config.");
-#endif
- }
- break;
- default:
- tb_assert(0);
- break;
- }
- }
- break;
- default:
- tb_assert(0);
- break;
- }
-
- // ok?
- return object;
-}
-static tb_object_ref_t tb_oc_bplist_reader_func_uid(tb_oc_bplist_reader_t* reader, tb_size_t type, tb_size_t size, tb_size_t item_size)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream, tb_null);
-
- // done
- tb_bool_t ok = tb_false;
- tb_object_ref_t uid = tb_null;
- tb_object_ref_t value = tb_null;
- do
- {
- // read uid value
- value = tb_oc_bplist_reader_func_number(reader, TB_OC_BPLIST_TYPE_UINT, size, item_size);
- tb_assert_and_check_break(value);
-
- // init uid object
- uid = tb_oc_dictionary_init(8, tb_false);
- tb_assert_and_check_break(uid);
-
- // save this uid value
- tb_oc_dictionary_insert(uid, "CF$UID", value);
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit value
- if (value) tb_object_exit(value);
- value = tb_null;
- }
-
- // ok?
- return uid;
-}
-static tb_object_ref_t tb_oc_bplist_reader_func_date(tb_oc_bplist_reader_t* reader, tb_size_t type, tb_size_t size, tb_size_t item_size)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream, tb_null);
-
- // the date data
- tb_object_ref_t data = tb_oc_bplist_reader_func_number(reader, TB_OC_BPLIST_TYPE_REAL, size, item_size);
- tb_assert_and_check_return_val(data, tb_null);
-
- // init date
- tb_object_ref_t date = tb_oc_date_init_from_time(tb_oc_bplist_reader_time_apple2host((tb_time_t)tb_oc_number_uint64(data)));
-
- // exit data
- tb_object_exit(data);
-
- // ok?
- return date;
-}
-static tb_object_ref_t tb_oc_bplist_reader_func_boolean(tb_oc_bplist_reader_t* reader, tb_size_t type, tb_size_t size, tb_size_t item_size)
-{
- // init
- tb_object_ref_t object = tb_null;
-
- // read
- switch (size)
- {
- case TB_OC_BPLIST_TYPE_TRUE:
- object = tb_oc_boolean_init(tb_true);
- break;
- case TB_OC_BPLIST_TYPE_FALSE:
- object = tb_oc_boolean_init(tb_false);
- break;
- default:
- tb_assert(0);
- break;
- }
- return object;
-}
-static tb_object_ref_t tb_oc_bplist_reader_func_dictionary(tb_oc_bplist_reader_t* reader, tb_size_t type, tb_size_t size, tb_size_t item_size)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream, tb_null);
-
- // init
- tb_object_ref_t object = tb_null;
-
- // size is too large?
- if (size == 0x0f)
- {
- // read size
- tb_long_t val = tb_oc_bplist_reader_func_size(reader, item_size);
- tb_assert_and_check_return_val(val >= 0, tb_null);
- size = (tb_size_t)val;
- }
-
- // init dictionary
- object = tb_oc_dictionary_init(TB_OC_DICTIONARY_SIZE_MICRO, tb_false);
- tb_assert_and_check_return_val(object, tb_null);
-
- // init items data
- if (size)
- {
- item_size <<= 1;
- tb_byte_t* data = tb_malloc_bytes(sizeof(tb_uint32_t) + (size * item_size));
- if (data)
- {
- if (tb_stream_bread(reader->stream, data + sizeof(tb_uint32_t), size * item_size))
- {
- tb_bits_set_u32_ne(data, (tb_uint32_t)size);
- tb_object_setp(object, data);
- }
- else tb_free(data);
- }
- }
-
- // ok?
- return object;
-}
-static tb_object_ref_t tb_oc_bplist_reader_done(tb_stream_ref_t stream)
-{
- // check
- tb_assert_and_check_return_val(stream, tb_null);
-
- // init root
- tb_object_ref_t root = tb_null;
-
- // init reader
- tb_oc_bplist_reader_t reader = {0};
- reader.stream = stream;
-
- // init size
- tb_hize_t size = tb_stream_size(stream);
- tb_assert_and_check_return_val(size, tb_null);
-
- // init data
- tb_byte_t data[32] = {0};
-
- // read magic & version
- if (!tb_stream_bread(stream, data, 8)) return tb_null;
-
- // check magic & version
- if (tb_strncmp((tb_char_t const*)data, "bplist00", 8)) return tb_null;
-
- // seek to tail
- if (!tb_stream_seek(stream, size - 26)) return tb_null;
-
- // read offset size
- tb_uint8_t offset_size = 0;
- if (!tb_stream_bread_u8(stream, &offset_size)) return tb_null;
-
- // read item size for array and dictionary
- tb_uint8_t item_size = 0;
- if (!tb_stream_bread_u8(stream, &item_size)) return tb_null;
-
- // read object count
- tb_uint64_t object_count = 0;
- if (!tb_stream_bread_u64_be(stream, &object_count)) return tb_null;
-
- // read root object
- tb_uint64_t root_object = 0;
- if (!tb_stream_bread_u64_be(stream, &root_object)) return tb_null;
-
- // read offset table index
- tb_uint64_t offset_table_index = 0;
- if (!tb_stream_bread_u64_be(stream, &offset_table_index)) return tb_null;
-
- // trace
- tb_trace_d("offset_size: %u", offset_size);
- tb_trace_d("item_size: %u", item_size);
- tb_trace_d("object_count: %llu", object_count);
- tb_trace_d("root_object: %llu", root_object);
- tb_trace_d("offset_table_index: %llu", offset_table_index);
-
- // check
- tb_assert_and_check_return_val(item_size && offset_size && object_count, tb_null);
-
- // init object hash
- tb_object_ref_t* object_hash = (tb_object_ref_t*)tb_malloc0(sizeof(tb_object_ref_t) * (tb_size_t)object_count);
- tb_assert_and_check_return_val(object_hash, tb_null);
-
- // done
- tb_bool_t failed = tb_false;
- do
- {
- // walk
- tb_size_t i = 0;
- for (i = 0; i < object_count; i++)
- {
- // seek to the offset entry
- if (!tb_stream_seek(stream, offset_table_index + i * offset_size))
- {
- failed = tb_true;
- break;
- }
-
- // read the object offset
- tb_value_t value;
- tb_hize_t offset = 0;
- switch (offset_size)
- {
- case 1:
- if (tb_stream_bread_u8(stream, &value.u8)) offset = value.u8;
- break;
- case 2:
- if (tb_stream_bread_u16_be(stream, &value.u16)) offset = value.u16;
- break;
- case 4:
- if (tb_stream_bread_u32_be(stream, &value.u32)) offset = value.u32;
- break;
- case 8:
- if (tb_stream_bread_u64_be(stream, &value.u64)) offset = value.u64;
- break;
- default:
- return tb_null;
- break;
- }
- tb_check_break(!failed);
-
- // seek to the object offset
- if (!tb_stream_seek(stream, offset))
- {
- failed = tb_true;
- break;
- }
-
- // read object
- object_hash[i] = tb_oc_bplist_reader_func_object(&reader, item_size);
- }
-
- // failed?
- tb_check_break(!failed);
-
- // build array and dictionary items
- for (i = 0; i < object_count; i++)
- {
- tb_object_ref_t object = object_hash[i];
- if (object)
- {
- switch (tb_object_type(object))
- {
- case TB_OBJECT_TYPE_ARRAY:
- {
- // the priv data
- tb_byte_t* priv = (tb_byte_t*)tb_object_getp(object);
- if (priv)
- {
- // count
- tb_size_t count = (tb_size_t)tb_bits_get_u32_ne(priv);
- if (count)
- {
- // goto item data
- tb_byte_t const* p = priv + sizeof(tb_uint32_t);
- // walk items
- tb_size_t j = 0;
- for (j = 0; j < count; j++)
- {
- // the item index
- tb_size_t item = tb_oc_bplist_bits_get(p + j * item_size, item_size);
- tb_assert(item < object_count && object_hash[item]);
-
- // append item
- if (item < object_count && object_hash[item])
- {
- tb_object_retain(object_hash[item]);
- tb_oc_array_append(object, object_hash[item]);
- }
- }
- }
-
- // exit priv
- tb_free(priv);
- tb_object_setp(object, tb_null);
- }
- }
- break;
- case TB_OBJECT_TYPE_DICTIONARY:
- {
- // the priv data
- tb_byte_t* priv = (tb_byte_t*)tb_object_getp(object);
- if (priv)
- {
- // count
- tb_size_t count = (tb_size_t)tb_bits_get_u32_ne(priv);
- if (count)
- {
- // goto item data
- tb_byte_t const* p = priv + sizeof(tb_uint32_t);
-
- // walk items
- tb_size_t j = 0;
- for (j = 0; j < count; j++)
- {
- // the key and val
- tb_size_t key = tb_oc_bplist_bits_get(p + j * item_size, item_size);
- tb_size_t val = tb_oc_bplist_bits_get(p + (count + j) * item_size, item_size);
- tb_assert(key < object_count && object_hash[key]);
- tb_assert(val < object_count && object_hash[val]);
-
- // append the key & val
- if (key < object_count && val < object_count && object_hash[key] && object_hash[val])
- {
- // key must be string now.
- tb_assert(tb_object_type(object_hash[key]) == TB_OBJECT_TYPE_STRING);
- if (tb_object_type(object_hash[key]) == TB_OBJECT_TYPE_STRING)
- {
- // set key => val
- tb_char_t const* skey = tb_oc_string_cstr(object_hash[key]);
- if (skey)
- {
- tb_object_retain(object_hash[val]);
- tb_oc_dictionary_insert(object, skey, object_hash[val]);
- }
- tb_assert(skey);
- }
- }
- }
- }
-
- // exit priv
- tb_free(priv);
- tb_object_setp(object, tb_null);
- }
- }
- break;
- default:
- break;
- }
- }
- }
-
- } while (0);
-
- // exit object hash
- if (object_hash)
- {
- // root
- if (root_object < object_count) root = object_hash[root_object];
-
- // refn--
- tb_size_t i;
- for (i = 0; i < object_count; i++)
- {
- if (object_hash[i] && i != root_object)
- tb_object_exit(object_hash[i]);
- }
-
- // exit object hash
- tb_free(object_hash);
- object_hash = tb_null;
- }
-
- // ok?
- return root;
-}
-static tb_size_t tb_oc_bplist_reader_probe(tb_stream_ref_t stream)
-{
- // check
- tb_assert_and_check_return_val(stream, 0);
-
- // need it
- tb_byte_t* p = tb_null;
- if (!tb_stream_need(stream, &p, 6)) return 0;
- tb_assert_and_check_return_val(p, 0);
-
- // ok?
- return !tb_strnicmp((tb_char_t const*)p, "bplist", 6)? 80 : 0;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-tb_oc_reader_t* tb_oc_bplist_reader()
-{
- // the reader
- static tb_oc_reader_t s_reader = {0};
-
- // init reader
- s_reader.read = tb_oc_bplist_reader_done;
- s_reader.probe = tb_oc_bplist_reader_probe;
-
- // init hooker
- s_reader.hooker = tb_hash_map_init(TB_HASH_MAP_BUCKET_SIZE_MICRO, tb_element_uint32(), tb_element_ptr(tb_null, tb_null));
- tb_assert_and_check_return_val(s_reader.hooker, tb_null);
-
- // hook reader
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)TB_OC_BPLIST_TYPE_DATE, tb_oc_bplist_reader_func_date);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)TB_OC_BPLIST_TYPE_DATA, tb_oc_bplist_reader_func_data);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)TB_OC_BPLIST_TYPE_UID, tb_oc_bplist_reader_func_uid);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)TB_OC_BPLIST_TYPE_ARRAY, tb_oc_bplist_reader_func_array);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)TB_OC_BPLIST_TYPE_STRING, tb_oc_bplist_reader_func_string);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)TB_OC_BPLIST_TYPE_UNICODE, tb_oc_bplist_reader_func_string);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)TB_OC_BPLIST_TYPE_UINT, tb_oc_bplist_reader_func_number);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)TB_OC_BPLIST_TYPE_REAL, tb_oc_bplist_reader_func_number);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)TB_OC_BPLIST_TYPE_NONE, tb_oc_bplist_reader_func_boolean);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)TB_OC_BPLIST_TYPE_SET, tb_oc_bplist_reader_func_dictionary);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)TB_OC_BPLIST_TYPE_DICT, tb_oc_bplist_reader_func_dictionary);
-
- // ok
- return &s_reader;
-}
-tb_bool_t tb_oc_bplist_reader_hook(tb_size_t type, tb_oc_bplist_reader_func_t func)
-{
- // check
- tb_assert_and_check_return_val(func, tb_false);
-
- // the reader
- tb_oc_reader_t* reader = tb_oc_reader_get(TB_OBJECT_FORMAT_BPLIST);
- tb_assert_and_check_return_val(reader && reader->hooker, tb_false);
-
- // hook it
- tb_hash_map_insert(reader->hooker, (tb_pointer_t)type, func);
-
- // ok
- return tb_true;
-}
-tb_oc_bplist_reader_func_t tb_oc_bplist_reader_func(tb_size_t type)
-{
- // the reader
- tb_oc_reader_t* reader = tb_oc_reader_get(TB_OBJECT_FORMAT_BPLIST);
- tb_assert_and_check_return_val(reader && reader->hooker, tb_null);
-
- // the func
- return (tb_oc_bplist_reader_func_t)tb_hash_map_get(reader->hooker, (tb_pointer_t)type);
-}
-
diff --git a/core/src/tbox/src/tbox/object/impl/reader/bplist.h b/core/src/tbox/src/tbox/object/impl/reader/bplist.h
deleted file mode 100644
index 834ff4714..000000000
--- a/core/src/tbox/src/tbox/object/impl/reader/bplist.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file bplist.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_IMPL_READER_BPLIST_H
-#define TB_OBJECT_IMPL_READER_BPLIST_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the bplist reader type
-typedef struct __tb_oc_bplist_reader_t
-{
- /// the stream
- tb_stream_ref_t stream;
-
-}tb_oc_bplist_reader_t;
-
-/// the bplist reader func type
-typedef tb_object_ref_t (*tb_oc_bplist_reader_func_t)(tb_oc_bplist_reader_t* reader, tb_size_t type, tb_size_t size, tb_size_t item_size);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! the bplist reader
- *
- * @return the bplist object reader
- */
-tb_oc_reader_t* tb_oc_bplist_reader(tb_noarg_t);
-
-/*! hook the bplist reader
- *
- * @param type the object type
- * @param func the reader func
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_bplist_reader_hook(tb_size_t type, tb_oc_bplist_reader_func_t func);
-
-/*! the bplist reader func
- *
- * @param type the object type
- *
- * @return the object reader func
- */
-tb_oc_bplist_reader_func_t tb_oc_bplist_reader_func(tb_size_t type);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/impl/reader/json.c b/core/src/tbox/src/tbox/object/impl/reader/json.c
deleted file mode 100644
index 0ad7f070d..000000000
--- a/core/src/tbox/src/tbox/object/impl/reader/json.c
+++ /dev/null
@@ -1,607 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file json.c
- * @ingroup object
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "oc_reader_json"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "json.h"
-#include "reader.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-// the array grow
-#ifdef __tb_small__
-# define TB_OC_JSON_READER_ARRAY_GROW (64)
-#else
-# define TB_OC_JSON_READER_ARRAY_GROW (256)
-#endif
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static tb_object_ref_t tb_oc_json_reader_func_null(tb_oc_json_reader_t* reader, tb_char_t type)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream, tb_null);
-
- // init data
- tb_static_string_t data;
- tb_char_t buff[256];
- if (!tb_static_string_init(&data, buff, 256)) return tb_null;
-
- // done
- tb_object_ref_t null = tb_null;
- do
- {
- // append character
- tb_static_string_chrcat(&data, type);
-
- // walk
- tb_bool_t failed = tb_false;
- while (!failed && tb_stream_left(reader->stream))
- {
- // need one character
- tb_byte_t* p = tb_null;
- if (!tb_stream_need(reader->stream, &p, 1) && p)
- {
- failed = tb_true;
- break;
- }
-
- // the character
- tb_char_t ch = *p;
-
- // append character
- if (tb_isalpha(ch)) tb_static_string_chrcat(&data, ch);
- else break;
-
- // skip it
- tb_stream_skip(reader->stream, 1);
- }
-
- // failed?
- tb_check_break(!failed);
-
- // check
- tb_assert_and_check_break(tb_static_string_size(&data));
-
- // trace
- tb_trace_d("null: %s", tb_static_string_cstr(&data));
-
- // null?
- if (!tb_stricmp(tb_static_string_cstr(&data), "null")) null = tb_oc_null_init();
-
- } while (0);
-
- // exit data
- tb_static_string_exit(&data);
-
- // ok?
- return null;
-}
-static tb_object_ref_t tb_oc_json_reader_func_array(tb_oc_json_reader_t* reader, tb_char_t type)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream && type == '[', tb_null);
-
- // init array
- tb_object_ref_t array = tb_oc_array_init(TB_OC_JSON_READER_ARRAY_GROW, tb_false);
- tb_assert_and_check_return_val(array, tb_null);
-
- // done
- tb_char_t ch;
- tb_bool_t ok = tb_true;
- while (ok && tb_stream_left(reader->stream))
- {
- // read one character
- if (!tb_stream_bread_s8(reader->stream, (tb_sint8_t*)&ch)) break;
-
- // end?
- if (ch == ']') break;
- // no space? skip ','
- else if (!tb_isspace(ch) && ch != ',')
- {
- // the func
- tb_oc_json_reader_func_t func = tb_oc_json_reader_func(ch);
- tb_assert_and_check_break_state(func, ok, tb_false);
-
- // read item
- tb_object_ref_t item = func(reader, ch);
- tb_assert_and_check_break_state(item, ok, tb_false);
-
- // append item
- tb_oc_array_append(array, item);
- }
- }
-
- // failed?
- if (!ok)
- {
- // exit it
- if (array) tb_object_exit(array);
- array = tb_null;
- }
-
- // ok?
- return array;
-}
-static tb_object_ref_t tb_oc_json_reader_func_string(tb_oc_json_reader_t* reader, tb_char_t type)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream && (type == '\"' || type == '\''), tb_null);
-
- // init data
- tb_string_t data;
- if (!tb_string_init(&data)) return tb_null;
-
- // walk
- tb_char_t ch;
- while (tb_stream_left(reader->stream))
- {
- // read one character
- if (!tb_stream_bread_s8(reader->stream, (tb_sint8_t*)&ch)) break;
-
- // end?
- if (ch == '\"' || ch == '\'') break;
- // the escaped character?
- else if (ch == '\\')
- {
- // read one character
- if (!tb_stream_bread_s8(reader->stream, (tb_sint8_t*)&ch)) break;
-
- // unicode?
- if (ch == 'u')
- {
-#ifdef TB_CONFIG_MODULE_HAVE_CHARSET
- // the unicode string
- tb_char_t unicode_str[5];
- if (!tb_stream_bread(reader->stream, (tb_byte_t*)unicode_str, 4)) break;
- unicode_str[4] = '\0';
-
- // the unicode value
- tb_uint16_t unicode_val = tb_s16toi32(unicode_str);
-
- // the utf8 stream
- tb_char_t utf8_data[16] = {0};
- tb_static_stream_t utf8_stream;
- tb_static_stream_init(&utf8_stream, (tb_byte_t*)utf8_data, sizeof(utf8_data));
-
- // the unicode stream
- tb_static_stream_t unicode_stream = {0};
- tb_static_stream_init(&unicode_stream, (tb_byte_t*)&unicode_val, 2);
-
- // unicode to utf8
- tb_long_t utf8_size = tb_charset_conv_bst(TB_CHARSET_TYPE_UCS2 | TB_CHARSET_TYPE_NE, TB_CHARSET_TYPE_UTF8, &unicode_stream, &utf8_stream);
- if (utf8_size > 0) tb_string_cstrncat(&data, utf8_data, utf8_size);
-#else
- // trace
- tb_trace1_e("unicode type is not supported, please enable charset module config if you want to use it!");
-
- // only append it
- tb_string_chrcat(&data, ch);
-#endif
- }
- // append escaped character
- else tb_string_chrcat(&data, ch);
- }
- // append character
- else tb_string_chrcat(&data, ch);
- }
-
- // init string
- tb_object_ref_t string = tb_oc_string_init_from_cstr(tb_string_cstr(&data));
-
- // trace
- tb_trace_d("string: %s", tb_string_cstr(&data));
-
- // exit data
- tb_string_exit(&data);
-
- // ok?
- return string;
-}
-static tb_object_ref_t tb_oc_json_reader_func_number(tb_oc_json_reader_t* reader, tb_char_t type)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream, tb_null);
-
- // init data
- tb_static_string_t data;
- tb_char_t buff[256];
- if (!tb_static_string_init(&data, buff, 256)) return tb_null;
-
- // done
- tb_object_ref_t number = tb_null;
- do
- {
- // append character
- tb_static_string_chrcat(&data, type);
-
- // walk
- tb_bool_t bs = (type == '-')? tb_true : tb_false;
- tb_bool_t bf = (type == '.')? tb_true : tb_false;
- tb_bool_t failed = tb_false;
- while (!failed && tb_stream_left(reader->stream))
- {
- // need one character
- tb_byte_t* p = tb_null;
- if (!tb_stream_need(reader->stream, &p, 1) && p)
- {
- failed = tb_true;
- break;
- }
-
- // the character
- tb_char_t ch = *p;
-
- // is float?
- if (!bf && ch == '.') bf = tb_true;
- else if (bf && ch == '.')
- {
- failed = tb_true;
- break;
- }
-
- // append character
- if (tb_isdigit10(ch) || ch == '.' || ch == 'e' || ch == 'E' || ch == '-' || ch == '+')
- tb_static_string_chrcat(&data, ch);
- else break;
-
- // skip it
- tb_stream_skip(reader->stream, 1);
- }
-
- // failed?
- tb_check_break(!failed);
-
- // check
- tb_assert_and_check_break(tb_static_string_size(&data));
-
- // trace
- tb_trace_d("number: %s", tb_static_string_cstr(&data));
-
- // init number
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- if (bf) number = tb_oc_number_init_from_float(tb_stof(tb_static_string_cstr(&data)));
-#else
- if (bf) tb_trace_noimpl();
-#endif
- else if (bs)
- {
- tb_sint64_t value = tb_stoi64(tb_static_string_cstr(&data));
- tb_size_t bytes = tb_object_need_bytes(-value);
- switch (bytes)
- {
- case 1: number = tb_oc_number_init_from_sint8((tb_sint8_t)value); break;
- case 2: number = tb_oc_number_init_from_sint16((tb_sint16_t)value); break;
- case 4: number = tb_oc_number_init_from_sint32((tb_sint32_t)value); break;
- case 8: number = tb_oc_number_init_from_sint64((tb_sint64_t)value); break;
- default: break;
- }
-
- }
- else
- {
- tb_uint64_t value = tb_stou64(tb_static_string_cstr(&data));
- tb_size_t bytes = tb_object_need_bytes(value);
- switch (bytes)
- {
- case 1: number = tb_oc_number_init_from_uint8((tb_uint8_t)value); break;
- case 2: number = tb_oc_number_init_from_uint16((tb_uint16_t)value); break;
- case 4: number = tb_oc_number_init_from_uint32((tb_uint32_t)value); break;
- case 8: number = tb_oc_number_init_from_uint64((tb_uint64_t)value); break;
- default: break;
- }
- }
-
- } while (0);
-
- // exit data
- tb_static_string_exit(&data);
-
- // ok?
- return number;
-}
-static tb_object_ref_t tb_oc_json_reader_func_boolean(tb_oc_json_reader_t* reader, tb_char_t type)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream, tb_null);
-
- // init data
- tb_static_string_t data;
- tb_char_t buff[256];
- if (!tb_static_string_init(&data, buff, 256)) return tb_null;
-
- // done
- tb_object_ref_t boolean = tb_null;
- do
- {
- // append character
- tb_static_string_chrcat(&data, type);
-
- // walk
- tb_bool_t failed = tb_false;
- while (!failed && tb_stream_left(reader->stream))
- {
- // need one character
- tb_byte_t* p = tb_null;
- if (!tb_stream_need(reader->stream, &p, 1) && p)
- {
- failed = tb_true;
- break;
- }
-
- // the character
- tb_char_t ch = *p;
-
- // append character
- if (tb_isalpha(ch)) tb_static_string_chrcat(&data, ch);
- else break;
-
- // skip it
- tb_stream_skip(reader->stream, 1);
- }
-
- // failed?
- tb_check_break(!failed);
-
- // check
- tb_assert_and_check_break(tb_static_string_size(&data));
-
- // trace
- tb_trace_d("boolean: %s", tb_static_string_cstr(&data));
-
- // true?
- if (!tb_stricmp(tb_static_string_cstr(&data), "true")) boolean = tb_oc_boolean_init(tb_true);
- // false?
- else if (!tb_stricmp(tb_static_string_cstr(&data), "false")) boolean = tb_oc_boolean_init(tb_false);
-
- } while (0);
-
- // exit data
- tb_static_string_exit(&data);
-
- // ok?
- return boolean;
-}
-static tb_object_ref_t tb_oc_json_reader_func_dictionary(tb_oc_json_reader_t* reader, tb_char_t type)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->stream && type == '{', tb_null);
-
- // init key name
- tb_static_string_t kname;
- tb_char_t kdata[8192];
- if (!tb_static_string_init(&kname, kdata, 8192)) return tb_null;
-
- // init dictionary
- tb_object_ref_t dictionary = tb_oc_dictionary_init(0, tb_false);
- tb_assert_and_check_return_val(dictionary, tb_null);
-
- // walk
- tb_char_t ch;
- tb_bool_t ok = tb_true;
- tb_bool_t bkey = tb_false;
- tb_size_t bstr = 0;
- while (ok && tb_stream_left(reader->stream))
- {
- // read one character
- if (!tb_stream_bread_s8(reader->stream, (tb_sint8_t*)&ch)) break;
-
- // end?
- if (ch == '}') break;
- // no space? skip ','
- else if (!tb_isspace(ch) && ch != ',')
- {
- // no key?
- if (!bkey)
- {
- // is str?
- if (ch == '\"' || ch == '\'') bstr = !bstr;
- // is key end?
- else if (!bstr && ch == ':') bkey = tb_true;
- // append key
- else if (bstr) tb_static_string_chrcat(&kname, ch);
- }
- // key ok? read val
- else
- {
- // trace
- tb_trace_d("key: %s", tb_static_string_cstr(&kname));
-
- // the func
- tb_oc_json_reader_func_t func = tb_oc_json_reader_func(ch);
- tb_assert_and_check_break_state(func, ok, tb_false);
-
- // read val
- tb_object_ref_t val = func(reader, ch);
- tb_assert_and_check_break_state(val, ok, tb_false);
-
- // set key => val
- tb_oc_dictionary_insert(dictionary, tb_static_string_cstr(&kname), val);
-
- // reset key
- bstr = 0;
- bkey = tb_false;
- tb_static_string_clear(&kname);
- }
- }
- }
-
- // failed?
- if (!ok)
- {
- // exit it
- if (dictionary) tb_object_exit(dictionary);
- dictionary = tb_null;
- }
-
- // exit key name
- tb_static_string_exit(&kname);
-
- // ok?
- return dictionary;
-}
-static tb_object_ref_t tb_oc_json_reader_done(tb_stream_ref_t stream)
-{
- // check
- tb_assert_and_check_return_val(stream, tb_null);
-
- // init reader
- tb_oc_json_reader_t reader = {0};
- reader.stream = stream;
-
- // skip spaces
- tb_char_t type = '\0';
- while (tb_stream_left(stream))
- {
- if (!tb_stream_bread_s8(stream, (tb_sint8_t*)&type)) break;
- if (!tb_isspace(type)) break;
- }
-
- // empty?
- tb_check_return_val(tb_stream_left(stream), tb_null);
-
- // the func
- tb_oc_json_reader_func_t func = tb_oc_json_reader_func(type);
- tb_assert_and_check_return_val(func, tb_null);
-
- // read it
- return func(&reader, type);
-}
-static tb_size_t tb_oc_json_reader_probe(tb_stream_ref_t stream)
-{
- // check
- tb_assert_and_check_return_val(stream, 0);
-
- // need it
- tb_byte_t* p = tb_null;
- if (!tb_stream_need(stream, &p, 5)) return 0;
- tb_assert_and_check_return_val(p, 0);
-
- // probe it
- tb_size_t s = 10;
- tb_byte_t* e = p + 5;
- for (; p < e && *p; p++)
- {
- if (*p == '{' || *p == '[')
- {
- s = 50;
- break;
- }
- else if (!tb_isgraph(*p))
- {
- s = 0;
- break;
- }
- }
-
- // ok?
- return s;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-tb_oc_reader_t* tb_oc_json_reader()
-{
- // the reader
- static tb_oc_reader_t s_reader = {0};
-
- // init reader
- s_reader.read = tb_oc_json_reader_done;
- s_reader.probe = tb_oc_json_reader_probe;
-
- // init hooker
- s_reader.hooker = tb_hash_map_init(TB_HASH_MAP_BUCKET_SIZE_MICRO, tb_element_uint8(), tb_element_ptr(tb_null, tb_null));
- tb_assert_and_check_return_val(s_reader.hooker, tb_null);
-
- // hook reader
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'n', tb_oc_json_reader_func_null);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'N', tb_oc_json_reader_func_null);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'[', tb_oc_json_reader_func_array);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'\'', tb_oc_json_reader_func_string);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'\"', tb_oc_json_reader_func_string);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'0', tb_oc_json_reader_func_number);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'1', tb_oc_json_reader_func_number);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'2', tb_oc_json_reader_func_number);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'3', tb_oc_json_reader_func_number);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'4', tb_oc_json_reader_func_number);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'5', tb_oc_json_reader_func_number);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'6', tb_oc_json_reader_func_number);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'7', tb_oc_json_reader_func_number);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'8', tb_oc_json_reader_func_number);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'9', tb_oc_json_reader_func_number);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'.', tb_oc_json_reader_func_number);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'-', tb_oc_json_reader_func_number);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'+', tb_oc_json_reader_func_number);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'e', tb_oc_json_reader_func_number);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'E', tb_oc_json_reader_func_number);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'t', tb_oc_json_reader_func_boolean);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'T', tb_oc_json_reader_func_boolean);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'f', tb_oc_json_reader_func_boolean);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'F', tb_oc_json_reader_func_boolean);
- tb_hash_map_insert(s_reader.hooker, (tb_pointer_t)'{', tb_oc_json_reader_func_dictionary);
-
- // ok
- return &s_reader;
-}
-tb_bool_t tb_oc_json_reader_hook(tb_char_t type, tb_oc_json_reader_func_t func)
-{
- // check
- tb_assert_and_check_return_val(type && func, tb_false);
-
- // the reader
- tb_oc_reader_t* reader = tb_oc_reader_get(TB_OBJECT_FORMAT_JSON);
- tb_assert_and_check_return_val(reader && reader->hooker, tb_false);
-
- // hook it
- tb_hash_map_insert(reader->hooker, (tb_pointer_t)(tb_size_t)type, func);
-
- // ok
- return tb_true;
-}
-tb_oc_json_reader_func_t tb_oc_json_reader_func(tb_char_t type)
-{
- // check
- tb_assert_and_check_return_val(type, tb_null);
-
- // the reader
- tb_oc_reader_t* reader = tb_oc_reader_get(TB_OBJECT_FORMAT_JSON);
- tb_assert_and_check_return_val(reader && reader->hooker, tb_null);
-
- // the func
- return (tb_oc_json_reader_func_t)tb_hash_map_get(reader->hooker, (tb_pointer_t)(tb_size_t)type);
-}
-
diff --git a/core/src/tbox/src/tbox/object/impl/reader/json.h b/core/src/tbox/src/tbox/object/impl/reader/json.h
deleted file mode 100644
index af0170656..000000000
--- a/core/src/tbox/src/tbox/object/impl/reader/json.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file json.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_IMPL_READER_JSON_H
-#define TB_OBJECT_IMPL_READER_JSON_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the json reader type
-typedef struct __tb_oc_json_reader_t
-{
- /// the stream
- tb_stream_ref_t stream;
-
-}tb_oc_json_reader_t;
-
-/// the json reader func type
-typedef tb_object_ref_t (*tb_oc_json_reader_func_t)(tb_oc_json_reader_t* reader, tb_char_t type);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! the json object reader
- *
- * @return the json object reader
- */
-tb_oc_reader_t* tb_oc_json_reader(tb_noarg_t);
-
-/*! hook the json reader
- *
- * @param type the object type name
- * @param func the reader func
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_json_reader_hook(tb_char_t type, tb_oc_json_reader_func_t func);
-
-/*! the json reader func
- *
- * @param type the object type name
- *
- * @return the object reader func
- */
-tb_oc_json_reader_func_t tb_oc_json_reader_func(tb_char_t type);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/impl/reader/prefix.h b/core/src/tbox/src/tbox/object/impl/reader/prefix.h
deleted file mode 100644
index 16bd0a032..000000000
--- a/core/src/tbox/src/tbox/object/impl/reader/prefix.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file prefix.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_READER_PREFIX_H
-#define TB_OBJECT_READER_PREFIX_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "../prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * inlines
- */
-static __tb_inline__ tb_void_t tb_oc_reader_bin_type_size(tb_stream_ref_t stream, tb_size_t* ptype, tb_uint64_t* psize)
-{
- // check
- tb_assert_and_check_return(stream);
-
- // clear it first
- if (ptype) *ptype = 0;
- if (psize) *psize = 0;
-
- // the flag
- tb_uint8_t flag = 0;
- tb_bool_t ok = tb_stream_bread_u8(stream, &flag);
- tb_assert_and_check_return(ok);
-
- // read type and size
- tb_size_t type = flag >> 4;
- tb_uint64_t size = flag & 0x0f;
- if (type == 0xf)
- {
- tb_uint8_t value = 0;
- if (tb_stream_bread_u8(stream, &value)) type = value;
- }
-
- // done
- tb_value_t value;
- switch (size)
- {
- case 0xc:
- if (tb_stream_bread_u8(stream, &value.u8)) size = value.u8;
- break;
- case 0xd:
- if (tb_stream_bread_u16_be(stream, &value.u16)) size = value.u16;
- break;
- case 0xe:
- if (tb_stream_bread_u32_be(stream, &value.u32)) size = value.u32;
- break;
- case 0xf:
- if (tb_stream_bread_u64_be(stream, &value.u64)) size = value.u64;
- break;
- default:
- break;
- }
-
- // trace
-// tb_trace_d("type: %lu, size: %llu", type, size);
-
- // save
- if (ptype) *ptype = type;
- if (psize) *psize = size;
-}
-
-#endif
diff --git a/core/src/tbox/src/tbox/object/impl/reader/reader.c b/core/src/tbox/src/tbox/object/impl/reader/reader.c
deleted file mode 100644
index a914e5ec5..000000000
--- a/core/src/tbox/src/tbox/object/impl/reader/reader.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file reader.c
- * @ingroup object
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "reader.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * globals
- */
-
-// the object reader
-static tb_oc_reader_t* g_reader[TB_OBJECT_FORMAT_MAXN] = {tb_null};
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_bool_t tb_oc_reader_set(tb_size_t format, tb_oc_reader_t* reader)
-{
- // check
- format &= 0x00ff;
- tb_assert_and_check_return_val(reader && (format < tb_arrayn(g_reader)), tb_false);
-
- // exit the older reader if exists
- tb_oc_reader_remove(format);
-
- // set
- g_reader[format] = reader;
-
- // ok
- return tb_true;
-}
-tb_void_t tb_oc_reader_remove(tb_size_t format)
-{
- // check
- format &= 0x00ff;
- tb_assert_and_check_return((format < tb_arrayn(g_reader)));
-
- // exit it
- if (g_reader[format])
- {
- // exit hooker
- if (g_reader[format]->hooker) tb_hash_map_exit(g_reader[format]->hooker);
- g_reader[format]->hooker = tb_null;
-
- // clear it
- g_reader[format] = tb_null;
- }
-}
-tb_oc_reader_t* tb_oc_reader_get(tb_size_t format)
-{
- // check
- format &= 0x00ff;
- tb_assert_and_check_return_val((format < tb_arrayn(g_reader)), tb_null);
-
- // ok
- return g_reader[format];
-}
-tb_object_ref_t tb_oc_reader_done(tb_stream_ref_t stream)
-{
- // check
- tb_assert_and_check_return_val(stream, tb_null);
-
- // probe it
- tb_size_t i = 0;
- tb_size_t n = tb_arrayn(g_reader);
- tb_size_t m = 0;
- tb_size_t f = 0;
- for (i = 0; i < n && m < 100; i++)
- {
- // the reader
- tb_oc_reader_t* reader = g_reader[i];
- if (reader && reader->probe)
- {
- // the probe score
- tb_size_t score = reader->probe(stream);
- if (score > m)
- {
- m = score;
- f = i;
- }
- }
- }
-
- // ok? read it
- return (m && g_reader[f] && g_reader[f]->read)? g_reader[f]->read(stream) : tb_null;
-}
diff --git a/core/src/tbox/src/tbox/object/impl/reader/reader.h b/core/src/tbox/src/tbox/object/impl/reader/reader.h
deleted file mode 100644
index a0823efec..000000000
--- a/core/src/tbox/src/tbox/object/impl/reader/reader.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file reader.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_IMPL_READER_H
-#define TB_OBJECT_IMPL_READER_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "xml.h"
-#include "bin.h"
-#include "json.h"
-#include "xplist.h"
-#include "bplist.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! set object reader
- *
- * @param format the reader format
- * @param reader the reader
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_reader_set(tb_size_t format, tb_oc_reader_t* reader);
-
-/*! get object reader
- *
- * @param format the reader format
- *
- * @return the object reader
- */
-tb_oc_reader_t* tb_oc_reader_get(tb_size_t format);
-
-/*! remove object reader
- *
- * @param format the reader format
- */
-tb_void_t tb_oc_reader_remove(tb_size_t format);
-
-/*! done reader
- *
- * @param stream the stream
- *
- * @return the object
- */
-tb_object_ref_t tb_oc_reader_done(tb_stream_ref_t stream);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/object/impl/reader/xml.c b/core/src/tbox/src/tbox/object/impl/reader/xml.c
deleted file mode 100644
index d6d21fd97..000000000
--- a/core/src/tbox/src/tbox/object/impl/reader/xml.c
+++ /dev/null
@@ -1,647 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file xml.c
- * @ingroup object
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "oc_reader_xml"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "xml.h"
-#include "reader.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-// the array grow
-#ifdef __tb_small__
-# define TB_OC_XML_READER_ARRAY_GROW (64)
-#else
-# define TB_OC_XML_READER_ARRAY_GROW (256)
-#endif
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static tb_object_ref_t tb_oc_xml_reader_func_null(tb_oc_xml_reader_t* reader, tb_size_t event)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->reader && event, tb_null);
-
- // ok
- return (tb_object_ref_t)tb_oc_null_init();
-}
-static tb_object_ref_t tb_oc_xml_reader_func_date(tb_oc_xml_reader_t* reader, tb_size_t event)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->reader && event, tb_null);
-
- // empty?
- if (event == TB_XML_READER_EVENT_ELEMENT_EMPTY)
- return tb_oc_date_init_from_time(0);
-
- // walk
- tb_object_ref_t date = tb_null;
- tb_bool_t leave = tb_false;
- while (!leave && (event = tb_xml_reader_next(reader->reader)))
- {
- switch (event)
- {
- case TB_XML_READER_EVENT_ELEMENT_END:
- {
- // name
- tb_char_t const* name = tb_xml_reader_element(reader->reader);
- tb_assert_and_check_break_state(name, leave, tb_true);
-
- // is end?
- if (!tb_stricmp(name, "date"))
- {
- // empty?
- if (!date) date = tb_oc_date_init_from_time(0);
-
- // leave it
- leave = tb_true;
- }
- }
- break;
- case TB_XML_READER_EVENT_TEXT:
- {
- // text
- tb_char_t const* text = tb_xml_reader_text(reader->reader);
- tb_assert_and_check_break_state(text, leave, tb_true);
- tb_trace_d("date: %s", text);
-
- // done date: %04ld-%02ld-%02ld %02ld:%02ld:%02ld
- tb_tm_t tm = {0};
- tb_char_t const* p = text;
- tb_char_t const* e = text + tb_strlen(text);
-
- // init year
- while (p < e && *p && !tb_isdigit(*p)) p++;
- tb_assert_and_check_break_state(p < e, leave, tb_true);
- tm.year = tb_atoi(p);
-
- // init month
- while (p < e && *p && tb_isdigit(*p)) p++;
- while (p < e && *p && !tb_isdigit(*p)) p++;
- tb_assert_and_check_break_state(p < e, leave, tb_true);
- tm.month = tb_atoi(p);
-
- // init day
- while (p < e && *p && tb_isdigit(*p)) p++;
- while (p < e && *p && !tb_isdigit(*p)) p++;
- tb_assert_and_check_break_state(p < e, leave, tb_true);
- tm.mday = tb_atoi(p);
-
- // init hour
- while (p < e && *p && tb_isdigit(*p)) p++;
- while (p < e && *p && !tb_isdigit(*p)) p++;
- tb_assert_and_check_break_state(p < e, leave, tb_true);
- tm.hour = tb_atoi(p);
-
- // init minute
- while (p < e && *p && tb_isdigit(*p)) p++;
- while (p < e && *p && !tb_isdigit(*p)) p++;
- tb_assert_and_check_break_state(p < e, leave, tb_true);
- tm.minute = tb_atoi(p);
-
- // init second
- while (p < e && *p && tb_isdigit(*p)) p++;
- while (p < e && *p && !tb_isdigit(*p)) p++;
- tb_assert_and_check_break_state(p < e, leave, tb_true);
- tm.second = tb_atoi(p);
-
- // time
- tb_time_t time = tb_mktime(&tm);
- tb_assert_and_check_break_state(time >= 0, leave, tb_true);
-
- // date
- date = tb_oc_date_init_from_time(time);
- }
- break;
- default:
- break;
- }
- }
-
- // ok?
- return date;
-}
-static tb_object_ref_t tb_oc_xml_reader_func_data(tb_oc_xml_reader_t* reader, tb_size_t event)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->reader && event, tb_null);
-
- // empty?
- if (event == TB_XML_READER_EVENT_ELEMENT_EMPTY)
- return tb_oc_data_init_from_data(tb_null, 0);
-
- // walk
- tb_object_ref_t data = tb_null;
- tb_char_t* base64 = tb_null;
- tb_bool_t leave = tb_false;
- while (!leave && (event = tb_xml_reader_next(reader->reader)))
- {
- switch (event)
- {
- case TB_XML_READER_EVENT_ELEMENT_END:
- {
- // name
- tb_char_t const* name = tb_xml_reader_element(reader->reader);
- tb_assert_and_check_break_state(name, leave, tb_true);
-
- // is end?
- if (!tb_stricmp(name, "data"))
- {
- // empty?
- if (!data) data = tb_oc_data_init_from_data(tb_null, 0);
-
- // leave it
- leave = tb_true;
- }
- }
- break;
- case TB_XML_READER_EVENT_TEXT:
- {
- // text
- tb_char_t const* text = tb_xml_reader_text(reader->reader);
- tb_assert_and_check_break_state(text, leave, tb_true);
- tb_trace_d("data: %s", text);
-
- // base64
- base64 = tb_strdup(text);
- tb_char_t* p = base64;
- tb_char_t* q = p;
- for (; *p; p++) if (!tb_isspace(*p)) *q++ = *p;
- *q = '\0';
-
- // decode base64 data
- tb_char_t const* ib = base64;
- tb_size_t in = tb_strlen(base64);
- if (in)
- {
- tb_size_t on = in;
- tb_byte_t* ob = tb_malloc0_bytes(on);
- tb_assert_and_check_break_state(ob && on, leave, tb_true);
- on = tb_base64_decode(ib, in, ob, on);
- tb_trace_d("base64: %u => %u", in, on);
-
- // init data
- data = tb_oc_data_init_from_data(ob, on); tb_free(ob);
- }
- else data = tb_oc_data_init_from_data(tb_null, 0);
- tb_assert_and_check_break_state(data, leave, tb_true);
- }
- break;
- default:
- break;
- }
- }
-
- // exit base64
- if (base64) tb_free(base64);
- base64 = tb_null;
-
- // ok?
- return data;
-}
-static tb_object_ref_t tb_oc_xml_reader_func_array(tb_oc_xml_reader_t* reader, tb_size_t event)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->reader && event, tb_null);
-
- // empty?
- if (event == TB_XML_READER_EVENT_ELEMENT_EMPTY)
- return tb_oc_array_init(TB_OC_XML_READER_ARRAY_GROW, tb_false);
-
- // init array
- tb_object_ref_t array = tb_oc_array_init(TB_OC_XML_READER_ARRAY_GROW, tb_false);
- tb_assert_and_check_return_val(array, tb_null);
-
- // done
- tb_long_t ok = 0;
- while (!ok && (event = tb_xml_reader_next(reader->reader)))
- {
- switch (event)
- {
- case TB_XML_READER_EVENT_ELEMENT_BEG:
- case TB_XML_READER_EVENT_ELEMENT_EMPTY:
- {
- // name
- tb_char_t const* name = tb_xml_reader_element(reader->reader);
- tb_assert_and_check_break_state(name, ok, -1);
- tb_trace_d("item: %s", name);
-
- // func
- tb_oc_xml_reader_func_t func = tb_oc_xml_reader_func(name);
- tb_assert_and_check_break_state(func, ok, -1);
-
- // read
- tb_object_ref_t object = func(reader, event);
-
- // append object
- if (object) tb_oc_array_append(array, object);
- }
- break;
- case TB_XML_READER_EVENT_ELEMENT_END:
- {
- // name
- tb_char_t const* name = tb_xml_reader_element(reader->reader);
- tb_assert_and_check_break_state(name, ok, -1);
-
- // is end?
- if (!tb_stricmp(name, "array")) ok = 1;
- }
- break;
- default:
- break;
- }
- }
-
- // failed?
- if (ok < 0)
- {
- // exit it
- if (array) tb_object_exit(array);
- array = tb_null;
- }
-
- // ok?
- return array;
-}
-static tb_object_ref_t tb_oc_xml_reader_func_string(tb_oc_xml_reader_t* reader, tb_size_t event)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->reader && event, tb_null);
-
- // empty?
- if (event == TB_XML_READER_EVENT_ELEMENT_EMPTY)
- return tb_oc_string_init_from_cstr(tb_null);
-
- // done
- tb_bool_t leave = tb_false;
- tb_object_ref_t string = tb_null;
- while (!leave && (event = tb_xml_reader_next(reader->reader)))
- {
- switch (event)
- {
- case TB_XML_READER_EVENT_ELEMENT_END:
- {
- // name
- tb_char_t const* name = tb_xml_reader_element(reader->reader);
- tb_assert_and_check_break_state(name, leave, tb_true);
-
- // is end?
- if (!tb_stricmp(name, "string"))
- {
- // empty?
- if (!string) string = tb_oc_string_init_from_cstr(tb_null);
-
- // leave it
- leave = tb_true;
- }
- }
- break;
- case TB_XML_READER_EVENT_TEXT:
- {
- // text
- tb_char_t const* text = tb_xml_reader_text(reader->reader);
- tb_assert_and_check_break_state(text, leave, tb_true);
- tb_trace_d("string: %s", text);
-
- // string
- string = tb_oc_string_init_from_cstr(text);
- tb_assert_and_check_break_state(string, leave, tb_true);
- }
- break;
- default:
- break;
- }
- }
-
- // ok?
- return string;
-}
-static tb_object_ref_t tb_oc_xml_reader_func_number(tb_oc_xml_reader_t* reader, tb_size_t event)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->reader && event, tb_null);
-
- // empty?
- if (event == TB_XML_READER_EVENT_ELEMENT_EMPTY)
- return tb_oc_number_init_from_uint32(0);
-
- // done
- tb_bool_t leave = tb_false;
- tb_object_ref_t number = tb_null;
- while (!leave && (event = tb_xml_reader_next(reader->reader)))
- {
- switch (event)
- {
- case TB_XML_READER_EVENT_ELEMENT_END:
- {
- // name
- tb_char_t const* name = tb_xml_reader_element(reader->reader);
- tb_assert_and_check_break_state(name, leave, tb_true);
-
- // is end?
- if (!tb_stricmp(name, "number")) leave = tb_true;
- }
- break;
- case TB_XML_READER_EVENT_TEXT:
- {
- // text
- tb_char_t const* text = tb_xml_reader_text(reader->reader);
- tb_assert_and_check_break_state(text, leave, tb_true);
- tb_trace_d("number: %s", text);
-
- // has sign? is float?
- tb_size_t s = 0;
- tb_size_t f = 0;
- tb_char_t const* p = text;
- for (; *p; p++)
- {
- if (!s && *p == '-') s = 1;
- if (!f && *p == '.') f = 1;
- if (s && f) break;
- }
-
- // number
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- if (f) number = tb_oc_number_init_from_double(tb_atof(text));
-#else
- if (f) tb_trace_noimpl();
-#endif
- else number = s? tb_oc_number_init_from_sint64(tb_stoi64(text)) : tb_oc_number_init_from_uint64(tb_stou64(text));
- tb_assert_and_check_break_state(number, leave, tb_true);
- }
- break;
- default:
- break;
- }
- }
-
- // ok?
- return number;
-}
-static tb_object_ref_t tb_oc_xml_reader_func_boolean(tb_oc_xml_reader_t* reader, tb_size_t event)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->reader && event, tb_null);
-
- // name
- tb_char_t const* name = tb_xml_reader_element(reader->reader);
- tb_assert_and_check_return_val(name, tb_null);
- tb_trace_d("boolean: %s", name);
-
- // the boolean value
- tb_bool_t val = tb_false;
- if (!tb_stricmp(name, "true")) val = tb_true;
- else if (!tb_stricmp(name, "false")) val = tb_false;
- else return tb_null;
-
- // ok?
- return (tb_object_ref_t)tb_oc_boolean_init(val);
-}
-static tb_object_ref_t tb_oc_xml_reader_func_dictionary(tb_oc_xml_reader_t* reader, tb_size_t event)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->reader && event, tb_null);
-
- // empty?
- if (event == TB_XML_READER_EVENT_ELEMENT_EMPTY)
- return tb_oc_dictionary_init(TB_OC_DICTIONARY_SIZE_MICRO, tb_false);
-
- // init key name
- tb_static_string_t kname;
- tb_char_t kdata[8192];
- if (!tb_static_string_init(&kname, kdata, 8192)) return tb_null;
-
- // init dictionary
- tb_object_ref_t dictionary = tb_oc_dictionary_init(0, tb_false);
- tb_assert_and_check_return_val(dictionary, tb_null);
-
- // walk
- tb_long_t ok = 0;
- tb_bool_t key = tb_false;
- while (!ok && (event = tb_xml_reader_next(reader->reader)))
- {
- switch (event)
- {
- case TB_XML_READER_EVENT_ELEMENT_BEG:
- case TB_XML_READER_EVENT_ELEMENT_EMPTY:
- {
- // name
- tb_char_t const* name = tb_xml_reader_element(reader->reader);
- tb_assert_and_check_break_state(name, ok, -1);
- tb_trace_d("%s", name);
-
- // is key
- if (!tb_stricmp(name, "key")) key = tb_true;
- else if (!key)
- {
- // func
- tb_oc_xml_reader_func_t func = tb_oc_xml_reader_func(name);
- tb_assert_and_check_break_state(func, ok, -1);
-
- // read
- tb_object_ref_t object = func(reader, event);
- tb_trace_d("%s => %p", tb_static_string_cstr(&kname), object);
- tb_assert_and_check_break_state(object, ok, -1);
-
- // set key & value
- if (tb_static_string_size(&kname) && dictionary)
- tb_oc_dictionary_insert(dictionary, tb_static_string_cstr(&kname), object);
-
- // clear key name
- tb_static_string_clear(&kname);
- }
- }
- break;
- case TB_XML_READER_EVENT_ELEMENT_END:
- {
- // name
- tb_char_t const* name = tb_xml_reader_element(reader->reader);
- tb_assert_and_check_break_state(name, ok, -1);
-
- // is end?
- if (!tb_stricmp(name, "dict")) ok = 1;
- else if (!tb_stricmp(name, "key")) key = tb_false;
- }
- break;
- case TB_XML_READER_EVENT_TEXT:
- {
- if (key)
- {
- // text
- tb_char_t const* text = tb_xml_reader_text(reader->reader);
- tb_assert_and_check_break_state(text, ok, -1);
-
- // writ key name
- tb_static_string_cstrcpy(&kname, text);
- }
- }
- break;
- default:
- break;
- }
- }
-
- // failed?
- if (ok < 0)
- {
- // exit it
- if (dictionary) tb_object_exit(dictionary);
- dictionary = tb_null;
- }
-
- // exit key name
- tb_static_string_exit(&kname);
-
- // ok?
- return dictionary;
-}
-static tb_object_ref_t tb_oc_xml_reader_done(tb_stream_ref_t stream)
-{
- // init reader
- tb_oc_xml_reader_t reader = {0};
- reader.reader = tb_xml_reader_init();
- tb_assert_and_check_return_val(reader.reader, tb_null);
-
- // open reader
- tb_object_ref_t object = tb_null;
- if (tb_xml_reader_open(reader.reader, stream, tb_false))
- {
- // done
- tb_bool_t leave = tb_false;
- tb_size_t event = TB_XML_READER_EVENT_NONE;
- while (!leave && !object && (event = tb_xml_reader_next(reader.reader)))
- {
- switch (event)
- {
- case TB_XML_READER_EVENT_ELEMENT_EMPTY:
- case TB_XML_READER_EVENT_ELEMENT_BEG:
- {
- // name
- tb_char_t const* name = tb_xml_reader_element(reader.reader);
- tb_assert_and_check_break_state(name, leave, tb_true);
-
- // func
- tb_oc_xml_reader_func_t func = tb_oc_xml_reader_func(name);
- tb_assert_and_check_break_state(func, leave, tb_true);
-
- // read
- object = func(&reader, event);
- }
- break;
- default:
- break;
- }
- }
- }
-
- // exit reader
- tb_xml_reader_exit(reader.reader);
-
- // ok?
- return object;
-}
-static tb_size_t tb_oc_xml_reader_probe(tb_stream_ref_t stream)
-{
- // check
- tb_assert_and_check_return_val(stream, 0);
-
- // need it
- tb_byte_t* p = tb_null;
- if (!tb_stream_need(stream, &p, 5)) return 0;
- tb_assert_and_check_return_val(p, 0);
-
- // ok?
- return !tb_strnicmp((tb_char_t const*)p, "<?xml", 5)? 50 : 0;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-tb_oc_reader_t* tb_oc_xml_reader()
-{
- // the reader
- static tb_oc_reader_t s_reader = {0};
-
- // init reader
- s_reader.read = tb_oc_xml_reader_done;
- s_reader.probe = tb_oc_xml_reader_probe;
-
- // init hooker
- s_reader.hooker = tb_hash_map_init(TB_HASH_MAP_BUCKET_SIZE_MICRO, tb_element_str(tb_false), tb_element_ptr(tb_null, tb_null));
- tb_assert_and_check_return_val(s_reader.hooker, tb_null);
-
- // hook reader
- tb_hash_map_insert(s_reader.hooker, "null", tb_oc_xml_reader_func_null);
- tb_hash_map_insert(s_reader.hooker, "date", tb_oc_xml_reader_func_date);
- tb_hash_map_insert(s_reader.hooker, "data", tb_oc_xml_reader_func_data);
- tb_hash_map_insert(s_reader.hooker, "array", tb_oc_xml_reader_func_array);
- tb_hash_map_insert(s_reader.hooker, "string", tb_oc_xml_reader_func_string);
- tb_hash_map_insert(s_reader.hooker, "number", tb_oc_xml_reader_func_number);
- tb_hash_map_insert(s_reader.hooker, "true", tb_oc_xml_reader_func_boolean);
- tb_hash_map_insert(s_reader.hooker, "false", tb_oc_xml_reader_func_boolean);
- tb_hash_map_insert(s_reader.hooker, "dict", tb_oc_xml_reader_func_dictionary);
-
- // ok
- return &s_reader;
-}
-tb_bool_t tb_oc_xml_reader_hook(tb_char_t const* type, tb_oc_xml_reader_func_t func)
-{
- // check
- tb_assert_and_check_return_val(type && func, tb_false);
-
- // the reader
- tb_oc_reader_t* reader = tb_oc_reader_get(TB_OBJECT_FORMAT_XML);
- tb_assert_and_check_return_val(reader && reader->hooker, tb_false);
-
- // hook it
- tb_hash_map_insert(reader->hooker, type, func);
-
- // ok
- return tb_true;
-}
-tb_oc_xml_reader_func_t tb_oc_xml_reader_func(tb_char_t const* type)
-{
- // check
- tb_assert_and_check_return_val(type, tb_null);
-
- // the reader
- tb_oc_reader_t* reader = tb_oc_reader_get(TB_OBJECT_FORMAT_XML);
- tb_assert_and_check_return_val(reader && reader->hooker, tb_null);
-
- // the func
- return (tb_oc_xml_reader_func_t)tb_hash_map_get(reader->hooker, type);
-}
-
diff --git a/core/src/tbox/src/tbox/object/impl/reader/xml.h b/core/src/tbox/src/tbox/object/impl/reader/xml.h
deleted file mode 100644
index f46a582fa..000000000
--- a/core/src/tbox/src/tbox/object/impl/reader/xml.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file xml.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_IMPL_READER_XML_H
-#define TB_OBJECT_IMPL_READER_XML_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the xml reader type
-typedef struct __tb_oc_xml_reader_t
-{
- /// the xml reader
- tb_xml_reader_ref_t reader;
-
-}tb_oc_xml_reader_t;
-
-/// the xml reader func type
-typedef tb_object_ref_t (*tb_oc_xml_reader_func_t)(tb_oc_xml_reader_t* reader, tb_size_t event);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! the xml object reader
- *
- * @return the xml object reader
- */
-tb_oc_reader_t* tb_oc_xml_reader(tb_noarg_t);
-
-/*! hook the xml reader
- *
- * @param type the object type name
- * @param func the reader func
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_xml_reader_hook(tb_char_t const* type, tb_oc_xml_reader_func_t func);
-
-/*! the xml reader func
- *
- * @param type the object type name
- *
- * @return the object reader func
- */
-tb_oc_xml_reader_func_t tb_oc_xml_reader_func(tb_char_t const* type);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/impl/reader/xplist.c b/core/src/tbox/src/tbox/object/impl/reader/xplist.c
deleted file mode 100644
index 3b2b18d1b..000000000
--- a/core/src/tbox/src/tbox/object/impl/reader/xplist.c
+++ /dev/null
@@ -1,653 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file xplist.c
- * @ingroup object
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "oc_reader_xplist"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "xplist.h"
-#include "reader.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-// the array grow
-#ifdef __tb_small__
-# define TB_OC_XPLIST_READER_ARRAY_GROW (64)
-#else
-# define TB_OC_XPLIST_READER_ARRAY_GROW (256)
-#endif
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static tb_object_ref_t tb_oc_xplist_reader_func_date(tb_oc_xplist_reader_t* reader, tb_size_t event)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->reader && event, tb_null);
-
- // empty?
- if (event == TB_XML_READER_EVENT_ELEMENT_EMPTY)
- return tb_oc_date_init_from_time(0);
-
- // done
- tb_bool_t leave = tb_false;
- tb_object_ref_t date = tb_null;
- while (!leave && (event = tb_xml_reader_next(reader->reader)))
- {
- switch (event)
- {
- case TB_XML_READER_EVENT_ELEMENT_END:
- {
- // name
- tb_char_t const* name = tb_xml_reader_element(reader->reader);
- tb_assert_and_check_break_state(name, leave, tb_true);
-
- // is end?
- if (!tb_stricmp(name, "date"))
- {
- // empty?
- if (!date) date = tb_oc_date_init_from_time(0);
-
- // leave it
- leave = tb_true;
- }
- }
- break;
- case TB_XML_READER_EVENT_TEXT:
- {
- // text
- tb_char_t const* text = tb_xml_reader_text(reader->reader);
- tb_assert_and_check_break_state(text, leave, tb_true);
- tb_trace_d("date: %s", text);
-
- // done date: %04ld-%02ld-%02ld %02ld:%02ld:%02ld
- tb_tm_t tm = {0};
- tb_char_t const* p = text;
- tb_char_t const* e = text + tb_strlen(text);
-
- // init year
- while (p < e && *p && !tb_isdigit(*p)) p++;
- tb_assert_and_check_break_state(p < e, leave, tb_true);
- tm.year = tb_atoi(p);
-
- // init month
- while (p < e && *p && tb_isdigit(*p)) p++;
- while (p < e && *p && !tb_isdigit(*p)) p++;
- tb_assert_and_check_break_state(p < e, leave, tb_true);
- tm.month = tb_atoi(p);
-
- // init day
- while (p < e && *p && tb_isdigit(*p)) p++;
- while (p < e && *p && !tb_isdigit(*p)) p++;
- tb_assert_and_check_break_state(p < e, leave, tb_true);
- tm.mday = tb_atoi(p);
-
- // init hour
- while (p < e && *p && tb_isdigit(*p)) p++;
- while (p < e && *p && !tb_isdigit(*p)) p++;
- tb_assert_and_check_break_state(p < e, leave, tb_true);
- tm.hour = tb_atoi(p);
-
- // init minute
- while (p < e && *p && tb_isdigit(*p)) p++;
- while (p < e && *p && !tb_isdigit(*p)) p++;
- tb_assert_and_check_break_state(p < e, leave, tb_true);
- tm.minute = tb_atoi(p);
-
- // init second
- while (p < e && *p && tb_isdigit(*p)) p++;
- while (p < e && *p && !tb_isdigit(*p)) p++;
- tb_assert_and_check_break_state(p < e, leave, tb_true);
- tm.second = tb_atoi(p);
-
- // time
- tb_time_t time = tb_mktime(&tm);
- tb_assert_and_check_break_state(time >= 0, leave, tb_true);
-
- // date
- date = tb_oc_date_init_from_time(time);
- }
- break;
- default:
- break;
- }
- }
-
- // ok?
- return date;
-}
-static tb_object_ref_t tb_oc_xplist_reader_func_data(tb_oc_xplist_reader_t* reader, tb_size_t event)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->reader && event, tb_null);
-
- // empty?
- if (event == TB_XML_READER_EVENT_ELEMENT_EMPTY)
- return tb_oc_data_init_from_data(tb_null, 0);
-
- // done
- tb_bool_t leave = tb_false;
- tb_char_t* base64 = tb_null;
- tb_object_ref_t data = tb_null;
- while (!leave && (event = tb_xml_reader_next(reader->reader)))
- {
- switch (event)
- {
- case TB_XML_READER_EVENT_ELEMENT_END:
- {
- // name
- tb_char_t const* name = tb_xml_reader_element(reader->reader);
- tb_assert_and_check_break_state(name, leave, tb_true);
-
- // is end?
- if (!tb_stricmp(name, "data"))
- {
- // empty?
- if (!data) data = tb_oc_data_init_from_data(tb_null, 0);
-
- // leave it
- leave = tb_true;
- }
- }
- break;
- case TB_XML_READER_EVENT_TEXT:
- {
- // text
- tb_char_t const* text = tb_xml_reader_text(reader->reader);
- tb_assert_and_check_break_state(text, leave, tb_true);
- tb_trace_d("data: %s", text);
-
- // base64
- base64 = tb_strdup(text);
- tb_char_t* p = base64;
- tb_char_t* q = p;
- for (; *p; p++) if (!tb_isspace(*p)) *q++ = *p;
- *q = '\0';
-
- // decode base64 data
- tb_char_t const* ib = base64;
- tb_size_t in = tb_strlen(base64);
- if (in)
- {
- tb_size_t on = in;
- tb_byte_t* ob = tb_malloc0_bytes(on);
- tb_assert_and_check_break_state(ob && on, leave, tb_true);
- on = tb_base64_decode(ib, in, ob, on);
- tb_trace_d("base64: %u => %u", in, on);
-
- // init data
- data = tb_oc_data_init_from_data(ob, on); tb_free(ob);
- }
- else data = tb_oc_data_init_from_data(tb_null, 0);
- tb_assert_and_check_break_state(data, leave, tb_true);
- }
- break;
- default:
- break;
- }
- }
-
- // free
- if (base64) tb_free(base64);
-
- // ok?
- return data;
-}
-static tb_object_ref_t tb_oc_xplist_reader_func_array(tb_oc_xplist_reader_t* reader, tb_size_t event)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->reader && event, tb_null);
-
- // empty?
- if (event == TB_XML_READER_EVENT_ELEMENT_EMPTY)
- return tb_oc_array_init(TB_OC_XPLIST_READER_ARRAY_GROW, tb_false);
-
- // init array
- tb_object_ref_t array = tb_oc_array_init(TB_OC_XPLIST_READER_ARRAY_GROW, tb_false);
- tb_assert_and_check_return_val(array, tb_null);
-
- // done
- tb_long_t ok = 0;
- while (!ok && (event = tb_xml_reader_next(reader->reader)))
- {
- switch (event)
- {
- case TB_XML_READER_EVENT_ELEMENT_BEG:
- case TB_XML_READER_EVENT_ELEMENT_EMPTY:
- {
- // name
- tb_char_t const* name = tb_xml_reader_element(reader->reader);
- tb_assert_and_check_break_state(name, ok, -1);
- tb_trace_d("item: %s", name);
-
- // func
- tb_oc_xplist_reader_func_t func = tb_oc_xplist_reader_func(name);
- tb_assert_and_check_break_state(func, ok, -1);
-
- // read
- tb_object_ref_t object = func(reader, event);
-
- // append object
- if (object) tb_oc_array_append(array, object);
- }
- break;
- case TB_XML_READER_EVENT_ELEMENT_END:
- {
- // name
- tb_char_t const* name = tb_xml_reader_element(reader->reader);
- tb_assert_and_check_break_state(name, ok, -1);
-
- // is end?
- if (!tb_stricmp(name, "array")) ok = 1;
- }
- break;
- default:
- break;
- }
- }
-
- // failed?
- if (ok < 0)
- {
- // exit it
- if (array) tb_object_exit(array);
- array = tb_null;
- }
-
- // ok?
- return array;
-}
-static tb_object_ref_t tb_oc_xplist_reader_func_string(tb_oc_xplist_reader_t* reader, tb_size_t event)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->reader && event, tb_null);
-
- // empty?
- if (event == TB_XML_READER_EVENT_ELEMENT_EMPTY)
- return tb_oc_string_init_from_cstr(tb_null);
-
- // done
- tb_bool_t leave = tb_false;
- tb_object_ref_t string = tb_null;
- while (!leave && (event = tb_xml_reader_next(reader->reader)))
- {
- switch (event)
- {
- case TB_XML_READER_EVENT_ELEMENT_END:
- {
- // name
- tb_char_t const* name = tb_xml_reader_element(reader->reader);
- tb_assert_and_check_break_state(name, leave, tb_true);
-
- // is end?
- if (!tb_stricmp(name, "string"))
- {
- // empty?
- if (!string) string = tb_oc_string_init_from_cstr(tb_null);
-
- // leave it
- leave = tb_true;
- }
- }
- break;
- case TB_XML_READER_EVENT_TEXT:
- {
- // text
- tb_char_t const* text = tb_xml_reader_text(reader->reader);
- tb_assert_and_check_break_state(text, leave, tb_true);
- tb_trace_d("string: %s", text);
-
- // string
- string = tb_oc_string_init_from_cstr(text);
- tb_assert_and_check_break_state(string, leave, tb_true);
- }
- break;
- default:
- break;
- }
- }
-
- // ok?
- return string;
-}
-static tb_object_ref_t tb_oc_xplist_reader_func_number(tb_oc_xplist_reader_t* reader, tb_size_t event)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->reader && event, tb_null);
-
- // empty?
- if (event == TB_XML_READER_EVENT_ELEMENT_EMPTY)
- return tb_oc_number_init_from_uint32(0);
-
- // done
- tb_bool_t leave = tb_false;
- tb_object_ref_t number = tb_null;
- while (!leave && (event = tb_xml_reader_next(reader->reader)))
- {
- switch (event)
- {
- case TB_XML_READER_EVENT_ELEMENT_END:
- {
- // name
- tb_char_t const* name = tb_xml_reader_element(reader->reader);
- tb_assert_and_check_break_state(name, leave, tb_true);
-
- // is end?
- if (!tb_stricmp(name, "integer") || !tb_stricmp(name, "real")) leave = tb_true;
- }
- break;
- case TB_XML_READER_EVENT_TEXT:
- {
- // text
- tb_char_t const* text = tb_xml_reader_text(reader->reader);
- tb_assert_and_check_break_state(text, leave, tb_true);
- tb_trace_d("number: %s", text);
-
- // has sign? is float?
- tb_size_t s = 0;
- tb_size_t f = 0;
- tb_char_t const* p = text;
- for (; *p; p++)
- {
- if (!s && *p == '-') s = 1;
- if (!f && *p == '.') f = 1;
- if (s && f) break;
- }
-
- // number
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- if (f) number = tb_oc_number_init_from_double(tb_atof(text));
-#else
- if (f) tb_trace_noimpl();
-#endif
- else number = s? tb_oc_number_init_from_sint64(tb_stoi64(text)) : tb_oc_number_init_from_uint64(tb_stou64(text));
- tb_assert_and_check_break_state(number, leave, tb_true);
- }
- break;
- default:
- break;
- }
- }
-
- // ok?
- return number;
-}
-static tb_object_ref_t tb_oc_xplist_reader_func_boolean(tb_oc_xplist_reader_t* reader, tb_size_t event)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->reader && event, tb_null);
-
- // name
- tb_char_t const* name = tb_xml_reader_element(reader->reader);
- tb_assert_and_check_return_val(name, tb_null);
- tb_trace_d("boolean: %s", name);
-
- // the boolean value
- tb_bool_t val = tb_false;
- if (!tb_stricmp(name, "true")) val = tb_true;
- else if (!tb_stricmp(name, "false")) val = tb_false;
- else return tb_null;
-
- // ok?
- return (tb_object_ref_t)tb_oc_boolean_init(val);
-}
-static tb_object_ref_t tb_oc_xplist_reader_func_dictionary(tb_oc_xplist_reader_t* reader, tb_size_t event)
-{
- // check
- tb_assert_and_check_return_val(reader && reader->reader && event, tb_null);
-
- // empty?
- if (event == TB_XML_READER_EVENT_ELEMENT_EMPTY)
- return tb_oc_dictionary_init(TB_OC_DICTIONARY_SIZE_MICRO, tb_false);
-
- // init key name
- tb_static_string_t kname;
- tb_char_t kdata[8192];
- if (!tb_static_string_init(&kname, kdata, 8192)) return tb_null;
-
- // init dictionary
- tb_object_ref_t dictionary = tb_oc_dictionary_init(0, tb_false);
- tb_assert_and_check_return_val(dictionary, tb_null);
-
- // done
- tb_long_t ok = 0;
- tb_bool_t key = tb_false;
- while (!ok && (event = tb_xml_reader_next(reader->reader)))
- {
- switch (event)
- {
- case TB_XML_READER_EVENT_ELEMENT_BEG:
- case TB_XML_READER_EVENT_ELEMENT_EMPTY:
- {
- // name
- tb_char_t const* name = tb_xml_reader_element(reader->reader);
- tb_assert_and_check_break_state(name, ok, -1);
- tb_trace_d("%s", name);
-
- // is key
- if (!tb_stricmp(name, "key")) key = tb_true;
- else if (!key)
- {
- // func
- tb_oc_xplist_reader_func_t func = tb_oc_xplist_reader_func(name);
- tb_assert_and_check_break_state(func, ok, -1);
-
- // read
- tb_object_ref_t object = func(reader, event);
- tb_trace_d("%s => %p", tb_static_string_cstr(&kname), object);
- tb_assert_and_check_break_state(object, ok, -1);
-
- // set key & value
- if (tb_static_string_size(&kname) && dictionary)
- tb_oc_dictionary_insert(dictionary, tb_static_string_cstr(&kname), object);
-
- // clear key name
- tb_static_string_clear(&kname);
- }
- }
- break;
- case TB_XML_READER_EVENT_ELEMENT_END:
- {
- // name
- tb_char_t const* name = tb_xml_reader_element(reader->reader);
- tb_assert_and_check_break_state(name, ok, -1);
-
- // is end?
- if (!tb_stricmp(name, "dict")) ok = 1;
- else if (!tb_stricmp(name, "key")) key = tb_false;
- }
- break;
- case TB_XML_READER_EVENT_TEXT:
- {
- if (key)
- {
- // text
- tb_char_t const* text = tb_xml_reader_text(reader->reader);
- tb_assert_and_check_break_state(text, ok, -1);
-
- // writ key name
- tb_static_string_cstrcpy(&kname, text);
- }
- }
- break;
- default:
- break;
- }
- }
-
- // failed
- if (ok < 0)
- {
- // exit it
- if (dictionary) tb_object_exit(dictionary);
- dictionary = tb_null;
- }
-
- // exit key name
- tb_static_string_exit(&kname);
-
- // ok?
- return dictionary;
-}
-static tb_object_ref_t tb_oc_xplist_reader_done(tb_stream_ref_t stream)
-{
- // init reader
- tb_oc_xplist_reader_t reader = {0};
- reader.reader = tb_xml_reader_init();
- tb_assert_and_check_return_val(reader.reader, tb_null);
-
- // open reader
- tb_object_ref_t object = tb_null;
- if (tb_xml_reader_open(reader.reader, stream, tb_false))
- {
- // done
- tb_bool_t leave = tb_false;
- tb_size_t event = TB_XML_READER_EVENT_NONE;
- while (!leave && !object && (event = tb_xml_reader_next(reader.reader)))
- {
- switch (event)
- {
- case TB_XML_READER_EVENT_ELEMENT_EMPTY:
- case TB_XML_READER_EVENT_ELEMENT_BEG:
- {
- // name
- tb_char_t const* name = tb_xml_reader_element(reader.reader);
- tb_assert_and_check_break_state(name, leave, tb_true);
-
- // <plist/> ?
- if (tb_stricmp(name, "plist"))
- {
- // func
- tb_oc_xplist_reader_func_t func = tb_oc_xplist_reader_func(name);
- tb_assert_and_check_break_state(func, leave, tb_true);
-
- // read
- object = func(&reader, event);
- }
- }
- break;
- default:
- break;
- }
- }
- }
-
- // exit reader
- tb_xml_reader_exit(reader.reader);
-
- // ok?
- return object;
-}
-static tb_size_t tb_oc_xplist_reader_probe(tb_stream_ref_t stream)
-{
- // check
- tb_assert_and_check_return_val(stream, 0);
-
- // need it
- tb_byte_t* p = tb_null;
- if (!tb_stream_need(stream, &p, 5)) return 0;
- tb_assert_and_check_return_val(p, 0);
-
- // is xml data?
- if (!tb_strnicmp((tb_char_t const*)p, "<?xml", 5))
- {
- // need more data
- if (!tb_stream_need(stream, &p, 256)) return 5;
- tb_assert_and_check_return_val(p, 5);
-
- // is xplist?
- return tb_strnistr((tb_char_t const*)p, 256, "DOCTYPE plist")? 80 : 10;
- }
-
- // ok?
- return 0;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-tb_oc_reader_t* tb_oc_xplist_reader()
-{
- // the reader
- static tb_oc_reader_t s_reader = {0};
-
- // init reader
- s_reader.read = tb_oc_xplist_reader_done;
- s_reader.probe = tb_oc_xplist_reader_probe;
-
- // init hooker
- s_reader.hooker = tb_hash_map_init(TB_HASH_MAP_BUCKET_SIZE_MICRO, tb_element_str(tb_false), tb_element_ptr(tb_null, tb_null));
- tb_assert_and_check_return_val(s_reader.hooker, tb_null);
-
- // hook reader
- tb_hash_map_insert(s_reader.hooker, "date", tb_oc_xplist_reader_func_date);
- tb_hash_map_insert(s_reader.hooker, "data", tb_oc_xplist_reader_func_data);
- tb_hash_map_insert(s_reader.hooker, "array", tb_oc_xplist_reader_func_array);
- tb_hash_map_insert(s_reader.hooker, "string", tb_oc_xplist_reader_func_string);
- tb_hash_map_insert(s_reader.hooker, "integer", tb_oc_xplist_reader_func_number);
- tb_hash_map_insert(s_reader.hooker, "real", tb_oc_xplist_reader_func_number);
- tb_hash_map_insert(s_reader.hooker, "true", tb_oc_xplist_reader_func_boolean);
- tb_hash_map_insert(s_reader.hooker, "false", tb_oc_xplist_reader_func_boolean);
- tb_hash_map_insert(s_reader.hooker, "dict", tb_oc_xplist_reader_func_dictionary);
-
- // ok
- return &s_reader;
-}
-tb_bool_t tb_oc_xplist_reader_hook(tb_char_t const* type, tb_oc_xplist_reader_func_t func)
-{
- // check
- tb_assert_and_check_return_val(type && func, tb_false);
-
- // the reader
- tb_oc_reader_t* reader = tb_oc_reader_get(TB_OBJECT_FORMAT_XPLIST);
- tb_assert_and_check_return_val(reader && reader->hooker, tb_false);
-
- // hook it
- tb_hash_map_insert(reader->hooker, type, func);
-
- // ok
- return tb_true;
-}
-tb_oc_xplist_reader_func_t tb_oc_xplist_reader_func(tb_char_t const* type)
-{
- // check
- tb_assert_and_check_return_val(type, tb_null);
-
- // the reader
- tb_oc_reader_t* reader = tb_oc_reader_get(TB_OBJECT_FORMAT_XPLIST);
- tb_assert_and_check_return_val(reader && reader->hooker, tb_null);
-
- // the func
- return (tb_oc_xplist_reader_func_t)tb_hash_map_get(reader->hooker, type);
-}
-
diff --git a/core/src/tbox/src/tbox/object/impl/reader/xplist.h b/core/src/tbox/src/tbox/object/impl/reader/xplist.h
deleted file mode 100644
index 4ba5d7d4a..000000000
--- a/core/src/tbox/src/tbox/object/impl/reader/xplist.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file xplist.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_IMPL_READER_XPLIST_H
-#define TB_OBJECT_IMPL_READER_XPLIST_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the xplist reader type
-typedef struct __tb_oc_xplist_reader_t
-{
- // the xplist reader
- tb_xml_reader_ref_t reader;
-
-}tb_oc_xplist_reader_t;
-
-// the xplist reader func type
-typedef tb_object_ref_t (*tb_oc_xplist_reader_func_t)(tb_oc_xplist_reader_t* reader, tb_size_t event);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/* the xplist object reader
- *
- * @return the xplist object reader
- */
-tb_oc_reader_t* tb_oc_xplist_reader(tb_noarg_t);
-
-/* hook the xplist reader
- *
- * @param type the object type name
- * @param func the reader func
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_xplist_reader_hook(tb_char_t const* type, tb_oc_xplist_reader_func_t func);
-
-/* the xplist reader func
- *
- * @param type the object type name
- *
- * @return the object reader func
- */
-tb_oc_xplist_reader_func_t tb_oc_xplist_reader_func(tb_char_t const* type);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/impl/writer/bin.c b/core/src/tbox/src/tbox/object/impl/writer/bin.c
deleted file mode 100644
index e85c51425..000000000
--- a/core/src/tbox/src/tbox/object/impl/writer/bin.c
+++ /dev/null
@@ -1,429 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file bin.c
- * @ingroup object
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "oc_writer_bin"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "bin.h"
-#include "writer.h"
-#include "../../../algorithm/algorithm.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static tb_bool_t tb_oc_bin_writer_func_null(tb_oc_bin_writer_t* writer, tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return_val(object && writer && writer->stream, tb_false);
-
- // writ type & null
- return tb_oc_writer_bin_type_size(writer->stream, object->type, 0);
-}
-static tb_bool_t tb_oc_bin_writer_func_date(tb_oc_bin_writer_t* writer, tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return_val(object && writer && writer->stream, tb_false);
-
- // writ type & time
- return tb_oc_writer_bin_type_size(writer->stream, object->type, (tb_uint64_t)tb_oc_date_time(object));
-}
-static tb_bool_t tb_oc_bin_writer_func_data(tb_oc_bin_writer_t* writer, tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return_val(object && writer && writer->stream, tb_false);
-
- // the data & size
- tb_byte_t const* data = (tb_byte_t const*)tb_oc_data_getp(object);
- tb_size_t size = tb_oc_data_size(object);
-
- // writ type & size
- if (!tb_oc_writer_bin_type_size(writer->stream, object->type, size)) return tb_false;
-
- // empty?
- tb_check_return_val(size, tb_true);
-
- // check
- tb_assert_and_check_return_val(data, tb_false);
-
- // make the encoder data
- if (!writer->data)
- {
- writer->maxn = tb_max(size, 8192);
- writer->data = tb_malloc0_bytes(writer->maxn);
- }
- else if (writer->maxn < size)
- {
- writer->maxn = size;
- writer->data = (tb_byte_t*)tb_ralloc(writer->data, writer->maxn);
- }
- tb_assert_and_check_return_val(writer->data && size <= writer->maxn, tb_false);
-
- // copy data to encoder
- tb_memcpy(writer->data, data, size);
-
- // encode data
- tb_byte_t const* pb = data;
- tb_byte_t const* pe = data + size;
- tb_byte_t* qb = writer->data;
- tb_byte_t* qe = writer->data + writer->maxn;
- tb_byte_t xb = (tb_byte_t)(((size >> 8) & 0xff) | (size & 0xff));
- for (; pb < pe && qb < qe; pb++, qb++, xb++) *qb = *pb ^ xb;
-
- // writ it
- return tb_stream_bwrit(writer->stream, writer->data, size);
-}
-static tb_bool_t tb_oc_bin_writer_func_array(tb_oc_bin_writer_t* writer, tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return_val(object && writer && writer->stream && writer->ohash, tb_false);
-
- // writ type & size
- if (!tb_oc_writer_bin_type_size(writer->stream, object->type, tb_oc_array_size(object))) return tb_false;
-
- // walk
- tb_for_all (tb_object_ref_t, item, tb_oc_array_itor(object))
- {
- if (item)
- {
- // exists?
- tb_size_t index = (tb_size_t)tb_hash_map_get(writer->ohash, item);
- if (index)
- {
- // writ index
- if (!tb_oc_writer_bin_type_size(writer->stream, 0, (tb_uint64_t)(index - 1))) return tb_false;
- }
- else
- {
- // the func
- tb_oc_bin_writer_func_t func = tb_oc_bin_writer_func(item->type);
- tb_assert_and_check_continue(func);
-
- // writ it
- if (!func(writer, item)) return tb_false;
-
- // save index
- tb_hash_map_insert(writer->ohash, item, (tb_cpointer_t)(++writer->index));
- }
- }
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_bin_writer_func_string(tb_oc_bin_writer_t* writer, tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return_val(object && writer && writer->stream, tb_false);
-
- // the data & size
- tb_char_t const* data = tb_oc_string_cstr(object);
- tb_size_t size = tb_oc_string_size(object);
-
- // writ type & size
- if (!tb_oc_writer_bin_type_size(writer->stream, object->type, size)) return tb_false;
-
- // empty?
- tb_check_return_val(size, tb_true);
-
- // check
- tb_assert_and_check_return_val(data, tb_false);
-
- // make the encoder data
- if (!writer->data)
- {
- writer->maxn = tb_max(size, 8192);
- writer->data = tb_malloc0_bytes(writer->maxn);
- }
- else if (writer->maxn < size)
- {
- writer->maxn = size;
- writer->data = (tb_byte_t*)tb_ralloc(writer->data, writer->maxn);
- }
- tb_assert_and_check_return_val(writer->data && size <= writer->maxn, tb_false);
-
- // copy data to encoder
- tb_memcpy(writer->data, data, size);
-
- // encode data
- tb_byte_t const* pb = (tb_byte_t const*)data;
- tb_byte_t const* pe = (tb_byte_t const*)data + size;
- tb_byte_t* qb = writer->data;
- tb_byte_t* qe = writer->data + writer->maxn;
- tb_byte_t xb = (tb_byte_t)(((size >> 8) & 0xff) | (size & 0xff));
- for (; pb < pe && qb < qe && *pb; pb++, qb++, xb++) *qb = *pb ^ xb;
-
- // writ it
- return tb_stream_bwrit(writer->stream, writer->data, size);
-}
-static tb_bool_t tb_oc_bin_writer_func_number(tb_oc_bin_writer_t* writer, tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return_val(object && writer && writer->stream, tb_false);
-
- // writ type
- if (!tb_oc_writer_bin_type_size(writer->stream, object->type, (tb_uint64_t)tb_oc_number_type(object))) return tb_false;
-
- // writ number
- switch (tb_oc_number_type(object))
- {
- case TB_OC_NUMBER_TYPE_UINT64:
- if (!tb_stream_bwrit_u64_be(writer->stream, tb_oc_number_uint64(object))) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_SINT64:
- if (!tb_stream_bwrit_s64_be(writer->stream, tb_oc_number_sint64(object))) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_UINT32:
- if (!tb_stream_bwrit_u32_be(writer->stream, tb_oc_number_uint32(object))) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_SINT32:
- if (!tb_stream_bwrit_s32_be(writer->stream, tb_oc_number_sint32(object))) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_UINT16:
- if (!tb_stream_bwrit_u16_be(writer->stream, tb_oc_number_uint16(object))) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_SINT16:
- if (!tb_stream_bwrit_s16_be(writer->stream, tb_oc_number_sint16(object))) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_UINT8:
- if (!tb_stream_bwrit_u8(writer->stream, tb_oc_number_uint8(object))) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_SINT8:
- if (!tb_stream_bwrit_s8(writer->stream, tb_oc_number_sint8(object))) return tb_false;
- break;
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- case TB_OC_NUMBER_TYPE_FLOAT:
- {
- tb_byte_t data[4];
- tb_bits_set_float_be(data, tb_oc_number_float(object));
- if (!tb_stream_bwrit(writer->stream, data, 4)) return tb_false;
- }
- break;
- case TB_OC_NUMBER_TYPE_DOUBLE:
- {
- tb_byte_t data[8];
- tb_bits_set_double_bbe(data, tb_oc_number_double(object));
- if (!tb_stream_bwrit(writer->stream, data, 8)) return tb_false;
- }
- break;
-#endif
- default:
- tb_assert_and_check_return_val(0, tb_false);
- break;
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_bin_writer_func_boolean(tb_oc_bin_writer_t* writer, tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return_val(object && writer && writer->stream, tb_false);
-
- // writ type & bool
- return tb_oc_writer_bin_type_size(writer->stream, object->type, tb_oc_boolean_bool(object));
-}
-static tb_bool_t tb_oc_bin_writer_func_dictionary(tb_oc_bin_writer_t* writer, tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return_val(object && writer && writer->stream && writer->ohash, tb_false);
-
- // writ type & size
- if (!tb_oc_writer_bin_type_size(writer->stream, object->type, tb_oc_dictionary_size(object))) return tb_false;
-
- // walk
- tb_for_all (tb_oc_dictionary_item_t*, item, tb_oc_dictionary_itor(object))
- {
- if (item)
- {
- tb_char_t const* key = item->key;
- tb_object_ref_t val = item->val;
- if (key && val)
- {
- // writ key
- {
- // exists?
- tb_size_t index = (tb_size_t)tb_hash_map_get(writer->shash, key);
- if (index)
- {
- // writ index
- if (!tb_oc_writer_bin_type_size(writer->stream, 0, (tb_uint64_t)(index - 1))) return tb_false;
- }
- else
- {
- // the func
- tb_oc_bin_writer_func_t func = tb_oc_bin_writer_func(TB_OBJECT_TYPE_STRING);
- tb_assert_and_check_return_val(func, tb_false);
-
- // make the key object
- tb_object_ref_t okey = tb_oc_string_init_from_cstr(key);
- tb_assert_and_check_return_val(okey, tb_false);
-
- // writ it
- if (!func(writer, okey)) return tb_false;
-
- // exit it
- tb_object_exit(okey);
-
- // save index
- tb_hash_map_insert(writer->shash, key, (tb_cpointer_t)(++writer->index));
- }
- }
-
- // writ val
- {
- // exists?
- tb_size_t index = (tb_size_t)tb_hash_map_get(writer->ohash, val);
- if (index)
- {
- // writ index
- if (!tb_oc_writer_bin_type_size(writer->stream, 0, (tb_uint64_t)(index - 1))) return tb_false;
- }
- else
- {
- // the func
- tb_oc_bin_writer_func_t func = tb_oc_bin_writer_func(val->type);
- tb_assert_and_check_return_val(func, tb_false);
-
- // writ it
- if (!func(writer, val)) return tb_false;
-
- // save index
- tb_hash_map_insert(writer->ohash, val, (tb_cpointer_t)(++writer->index));
- }
- }
- }
- }
- }
-
- // ok
- return tb_true;
-}
-static tb_long_t tb_oc_bin_writer_done(tb_stream_ref_t stream, tb_object_ref_t object, tb_bool_t deflate)
-{
- // check
- tb_assert_and_check_return_val(object && stream, -1);
-
- // the func
- tb_oc_bin_writer_func_t func = tb_oc_bin_writer_func(object->type);
- tb_assert_and_check_return_val(func, -1);
-
- // the begin offset
- tb_hize_t bof = tb_stream_offset(stream);
-
- // writ bin header
- if (!tb_stream_bwrit(stream, (tb_byte_t const*)"tbo00", 5)) return -1;
-
- // done
- tb_oc_bin_writer_t writer = {0};
- do
- {
- // init writer
- writer.stream = stream;
- writer.ohash = tb_hash_map_init(TB_HASH_MAP_BUCKET_SIZE_MICRO, tb_element_ptr(tb_null, tb_null), tb_element_uint32());
- writer.shash = tb_hash_map_init(TB_HASH_MAP_BUCKET_SIZE_MICRO, tb_element_str(tb_true), tb_element_uint32());
- tb_assert_and_check_break(writer.shash && writer.ohash);
-
- // writ
- if (!func(&writer, object)) break;
-
- // sync
- if (!tb_stream_sync(stream, tb_true)) break;
-
- } while (0);
-
- // exit the hash
- if (writer.ohash) tb_hash_map_exit(writer.ohash);
- if (writer.shash) tb_hash_map_exit(writer.shash);
-
- // exit the data
- if (writer.data) tb_free(writer.data);
-
- // the end offset
- tb_hize_t eof = tb_stream_offset(stream);
-
- // ok?
- return eof >= bof? (tb_long_t)(eof - bof) : -1;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-tb_oc_writer_t* tb_oc_bin_writer()
-{
- // the writer
- static tb_oc_writer_t s_writer = {0};
-
- // init writer
- s_writer.writ = tb_oc_bin_writer_done;
-
- // init hooker
- s_writer.hooker = tb_hash_map_init(TB_HASH_MAP_BUCKET_SIZE_MICRO, tb_element_uint32(), tb_element_ptr(tb_null, tb_null));
- tb_assert_and_check_return_val(s_writer.hooker, tb_null);
-
- // hook writer
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_NULL, tb_oc_bin_writer_func_null);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_DATE, tb_oc_bin_writer_func_date);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_DATA, tb_oc_bin_writer_func_data);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_ARRAY, tb_oc_bin_writer_func_array);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_STRING, tb_oc_bin_writer_func_string);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_NUMBER, tb_oc_bin_writer_func_number);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_BOOLEAN, tb_oc_bin_writer_func_boolean);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_DICTIONARY, tb_oc_bin_writer_func_dictionary);
-
- // ok
- return &s_writer;
-}
-tb_bool_t tb_oc_bin_writer_hook(tb_size_t type, tb_oc_bin_writer_func_t func)
-{
- // check
- tb_assert_and_check_return_val(func, tb_false);
-
- // the writer
- tb_oc_writer_t* writer = tb_oc_writer_get(TB_OBJECT_FORMAT_BIN);
- tb_assert_and_check_return_val(writer && writer->hooker, tb_false);
-
- // hook it
- tb_hash_map_insert(writer->hooker, (tb_pointer_t)type, func);
-
- // ok
- return tb_true;
-}
-tb_oc_bin_writer_func_t tb_oc_bin_writer_func(tb_size_t type)
-{
- // the writer
- tb_oc_writer_t* writer = tb_oc_writer_get(TB_OBJECT_FORMAT_BIN);
- tb_assert_and_check_return_val(writer && writer->hooker, tb_null);
-
- // the func
- return (tb_oc_bin_writer_func_t)tb_hash_map_get(writer->hooker, (tb_pointer_t)type);
-}
-
diff --git a/core/src/tbox/src/tbox/object/impl/writer/bin.h b/core/src/tbox/src/tbox/object/impl/writer/bin.h
deleted file mode 100644
index fdc68d09a..000000000
--- a/core/src/tbox/src/tbox/object/impl/writer/bin.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file bin.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_IMPL_WRITER_BIN_H
-#define TB_OBJECT_IMPL_WRITER_BIN_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the object bin writer type
-typedef struct __tb_oc_bin_writer_t
-{
- /// the stream
- tb_stream_ref_t stream;
-
- /// the object hash
- tb_hash_map_ref_t ohash;
-
- /// the string hash
- tb_hash_map_ref_t shash;
-
- /// the object index
- tb_size_t index;
-
- /// the encoder data
- tb_byte_t* data;
-
- /// the encoder maxn
- tb_size_t maxn;
-
-}tb_oc_bin_writer_t;
-
-/// the bin writer func type
-typedef tb_bool_t (*tb_oc_bin_writer_func_t)(tb_oc_bin_writer_t* writer, tb_object_ref_t object);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! the bin object writer
- *
- * @return the bin object writer
- */
-tb_oc_writer_t* tb_oc_bin_writer(tb_noarg_t);
-
-/*! hook the bin writer
- *
- * @param type the object type
- * @param func the writer func
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_bin_writer_hook(tb_size_t type, tb_oc_bin_writer_func_t func);
-
-/*! the bin writer func
- *
- * @param type the object type
- *
- * @return the object writer func
- */
-tb_oc_bin_writer_func_t tb_oc_bin_writer_func(tb_size_t type);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/impl/writer/bplist.c b/core/src/tbox/src/tbox/object/impl/writer/bplist.c
deleted file mode 100644
index d3887aeca..000000000
--- a/core/src/tbox/src/tbox/object/impl/writer/bplist.c
+++ /dev/null
@@ -1,806 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file bplist.c
- * @ingroup object
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "oc_writer_bplist"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "bplist.h"
-#include "writer.h"
-#include "../../../algorithm/algorithm.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-// set bits
-#define tb_oc_bplist_writer_bits_set(p, v, n) \
-do { \
- switch ((n)) \
- { \
- case 1: tb_bits_set_u8((p), (tb_uint8_t)(v)); break; \
- case 2: tb_bits_set_u16_be((p), (tb_uint16_t)(v)); break; \
- case 4: tb_bits_set_u32_be((p), (tb_uint32_t)(v)); break; \
- case 8: tb_bits_set_u64_be((p), (tb_uint64_t)(v)); break; \
- default: break; \
- } \
-} while (0)
-
-// number
-#define tb_oc_bplist_writer_init_number(x) \
-(((tb_uint64_t)(x)) < (1ull << 8) ? tb_oc_number_init_from_uint8((tb_uint8_t)(x)) : \
-(((tb_uint64_t)(x)) < (1ull << 16) ? tb_oc_number_init_from_uint16((tb_uint16_t)(x)) : \
-(((tb_uint64_t)(x)) < (1ull << 32) ? tb_oc_number_init_from_uint32((tb_uint32_t)(x)) : tb_oc_number_init_from_uint64((x)))))
-
-// object list grow
-#ifdef __tb_small__
-# define TB_OBJECT_BPLIST_LIST_GROW (64)
-#else
-# define TB_OBJECT_BPLIST_LIST_GROW (256)
-#endif
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the bplist type enum
-typedef enum __tb_oc_bplist_type_e
-{
- TB_OBJECT_BPLIST_TYPE_NONE = 0x00
-, TB_OBJECT_BPLIST_TYPE_FALSE = 0x08
-, TB_OBJECT_BPLIST_TYPE_TRUE = 0x09
-, TB_OBJECT_BPLIST_TYPE_UINT = 0x10
-, TB_OBJECT_BPLIST_TYPE_REAL = 0x20
-, TB_OBJECT_BPLIST_TYPE_DATE = 0x30
-, TB_OBJECT_BPLIST_TYPE_DATA = 0x40
-, TB_OBJECT_BPLIST_TYPE_STRING = 0x50
-, TB_OBJECT_BPLIST_TYPE_UNICODE = 0x60
-, TB_OBJECT_BPLIST_TYPE_UID = 0x70
-, TB_OBJECT_BPLIST_TYPE_ARRAY = 0xA0
-, TB_OBJECT_BPLIST_TYPE_SET = 0xC0
-, TB_OBJECT_BPLIST_TYPE_DICT = 0xD0
-, TB_OBJECT_BPLIST_TYPE_MASK = 0xF0
-
-}tb_oc_bplist_type_e;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * declaration
- */
-static tb_bool_t tb_oc_bplist_writer_func_number(tb_oc_bplist_writer_t* writer, tb_object_ref_t object, tb_size_t item_size);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
-static __tb_inline__ tb_time_t tb_oc_bplist_writer_time_host2apple(tb_time_t time)
-{
- tb_tm_t tm = {0};
- if (tb_localtime(time, &tm))
- {
- if (tm.year >= 31) tm.year -= 31;
- time = tb_mktime(&tm);
- }
- return time;
-}
-#endif
-static tb_bool_t tb_oc_bplist_writer_func_rdata(tb_oc_bplist_writer_t* writer, tb_uint8_t bype, tb_byte_t const* data, tb_size_t size, tb_size_t item_size)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream && !data == !size, tb_false);
-
- // writ flag
- tb_uint8_t flag = bype | (tb_uint8_t)(size < 15 ? size : 0xf);
- if (!tb_stream_bwrit_u8(writer->stream, flag)) return tb_false;
-
- // writ size
- if (size >= 15)
- {
- // init object
- tb_object_ref_t object = tb_oc_bplist_writer_init_number(size);
- tb_assert_and_check_return_val(object, tb_false);
-
- // writ it
- if (!tb_oc_bplist_writer_func_number(writer, object, item_size))
- {
- tb_object_exit(object);
- return tb_false;
- }
-
- // exit object
- tb_object_exit(object);
- }
-
- // unicode? adjust size
- if (bype == TB_OBJECT_BPLIST_TYPE_UNICODE) size <<= 1;
-
- // writ data
- if (data) if (!tb_stream_bwrit(writer->stream, data, size)) return tb_false;
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_bplist_writer_func_date(tb_oc_bplist_writer_t* writer, tb_object_ref_t object, tb_size_t item_size)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream && object, tb_false);
-
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- // writ date time
- if (!tb_stream_bwrit_u8(writer->stream, TB_OBJECT_BPLIST_TYPE_DATE | 3)) return tb_false;
- if (!tb_stream_bwrit_double_bbe(writer->stream, (tb_double_t)tb_oc_bplist_writer_time_host2apple(tb_oc_date_time(object)))) return tb_false;
-#else
- tb_assert_and_check_return_val(0, tb_false);
-#endif
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_bplist_writer_func_data(tb_oc_bplist_writer_t* writer, tb_object_ref_t object, tb_size_t item_size)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream && object, tb_false);
-
- // writ
- return tb_oc_bplist_writer_func_rdata(writer, TB_OBJECT_BPLIST_TYPE_DATA, (tb_byte_t const*)tb_oc_data_getp(object), tb_oc_data_size(object), item_size);
-}
-static tb_bool_t tb_oc_bplist_writer_func_array(tb_oc_bplist_writer_t* writer, tb_object_ref_t object, tb_size_t item_size)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream && object, tb_false);
-
- // index tables
- tb_byte_t* index_tables = (tb_byte_t*)tb_object_getp(object);
-
- // size
- tb_size_t size = tb_oc_array_size(object);
- tb_assert_and_check_return_val(!size == !index_tables, tb_false);
-
- // writ flag
- tb_uint8_t flag = TB_OBJECT_BPLIST_TYPE_ARRAY | (size < 15 ? (tb_uint8_t)size : 0xf);
- if (!tb_stream_bwrit_u8(writer->stream, flag)) return tb_false;
-
- // writ size
- if (size >= 15)
- {
- // init osize
- tb_object_ref_t osize = tb_oc_bplist_writer_init_number(size);
- tb_assert_and_check_return_val(osize, tb_false);
-
- // writ it
- if (!tb_oc_bplist_writer_func_number(writer, osize, item_size))
- {
- tb_object_exit(osize);
- return tb_false;
- }
-
- // exit osize
- tb_object_exit(osize);
- }
-
- // writ index tables
- if (index_tables)
- {
- if (!tb_stream_bwrit(writer->stream, index_tables, size * item_size)) return tb_false;
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_bplist_writer_func_string(tb_oc_bplist_writer_t* writer, tb_object_ref_t object, tb_size_t item_size)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream && object, tb_false);
-#if 0
- // writ utf8
- return tb_oc_bplist_writer_func_rdata(writer, TB_OBJECT_BPLIST_TYPE_STRING, tb_oc_string_cstr(object), tb_oc_string_size(object), item_size);
-#else
- // writ utf16
- tb_char_t const* utf8 = tb_oc_string_cstr(object);
- tb_size_t size = tb_oc_string_size(object);
- if (utf8 && size)
- {
-#ifdef TB_CONFIG_MODULE_HAVE_CHARSET
- // done
- tb_bool_t ok = tb_false;
- tb_char_t* utf16 = tb_null;
- tb_size_t osize = 0;
- do
- {
- // init utf16 data
- utf16 = tb_malloc_cstr((size + 1) << 2);
- tb_assert_and_check_break(utf16);
-
- // utf8 to utf16
- osize = tb_charset_conv_data(TB_CHARSET_TYPE_UTF8, TB_CHARSET_TYPE_UTF16, (tb_byte_t const*)utf8, size, (tb_byte_t*)utf16, (size + 1) << 2);
- tb_assert_and_check_break(osize > 0 && osize < (size + 1) << 2);
- tb_assert_and_check_break(!(osize & 1));
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // ok?
- if (ok)
- {
- // only ascii? writ utf8
- if (osize == (size << 1)) ok = tb_oc_bplist_writer_func_rdata(writer, TB_OBJECT_BPLIST_TYPE_STRING, (tb_byte_t*)utf8, size, item_size);
- // writ utf16
- else ok = tb_oc_bplist_writer_func_rdata(writer, TB_OBJECT_BPLIST_TYPE_UNICODE, (tb_byte_t*)utf16, osize >> 1, item_size);
-
- }
-
- // exit utf16
- if (utf16) tb_free(utf16);
- utf16 = tb_null;
-#else
- // writ utf8 only
- tb_bool_t ok = tb_oc_bplist_writer_func_rdata(writer, TB_OBJECT_BPLIST_TYPE_STRING, (tb_byte_t*)utf8, size, item_size);
-#endif
-
- // ok?
- return ok;
- }
- // writ empty
- else return tb_oc_bplist_writer_func_rdata(writer, TB_OBJECT_BPLIST_TYPE_STRING, tb_null, 0, item_size);
-#endif
-}
-static tb_bool_t tb_oc_bplist_writer_func_number(tb_oc_bplist_writer_t* writer, tb_object_ref_t object, tb_size_t item_size)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream && object, tb_false);
-
- // done
- switch (tb_oc_number_type(object))
- {
- case TB_OC_NUMBER_TYPE_UINT64:
- if (!tb_stream_bwrit_u8(writer->stream, TB_OBJECT_BPLIST_TYPE_UINT | 3)) return tb_false;
- if (!tb_stream_bwrit_u64_be(writer->stream, tb_oc_number_uint64(object))) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_SINT64:
- if (!tb_stream_bwrit_u8(writer->stream, TB_OBJECT_BPLIST_TYPE_UINT | 3)) return tb_false;
- if (!tb_stream_bwrit_s64_be(writer->stream, tb_oc_number_sint64(object))) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_UINT32:
- if (!tb_stream_bwrit_u8(writer->stream, TB_OBJECT_BPLIST_TYPE_UINT | 2)) return tb_false;
- if (!tb_stream_bwrit_u32_be(writer->stream, tb_oc_number_uint32(object))) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_SINT32:
- if (!tb_stream_bwrit_u8(writer->stream, TB_OBJECT_BPLIST_TYPE_UINT | 2)) return tb_false;
- if (!tb_stream_bwrit_s32_be(writer->stream, tb_oc_number_sint32(object))) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_UINT16:
- if (!tb_stream_bwrit_u8(writer->stream, TB_OBJECT_BPLIST_TYPE_UINT | 1)) return tb_false;
- if (!tb_stream_bwrit_u16_be(writer->stream, tb_oc_number_uint16(object))) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_SINT16:
- if (!tb_stream_bwrit_u8(writer->stream, TB_OBJECT_BPLIST_TYPE_UINT | 1)) return tb_false;
- if (!tb_stream_bwrit_s16_be(writer->stream, tb_oc_number_sint16(object))) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_UINT8:
- if (!tb_stream_bwrit_u8(writer->stream, TB_OBJECT_BPLIST_TYPE_UINT)) return tb_false;
- if (!tb_stream_bwrit_u8(writer->stream, tb_oc_number_uint8(object))) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_SINT8:
- if (!tb_stream_bwrit_u8(writer->stream, TB_OBJECT_BPLIST_TYPE_UINT)) return tb_false;
- if (!tb_stream_bwrit_s8(writer->stream, tb_oc_number_sint8(object))) return tb_false;
- break;
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- case TB_OC_NUMBER_TYPE_FLOAT:
- {
- if (!tb_stream_bwrit_u8(writer->stream, TB_OBJECT_BPLIST_TYPE_REAL | 2)) return tb_false;
- if (!tb_stream_bwrit_float_be(writer->stream, tb_oc_number_float(object))) return tb_false;
- }
- break;
- case TB_OC_NUMBER_TYPE_DOUBLE:
- {
- if (!tb_stream_bwrit_u8(writer->stream, TB_OBJECT_BPLIST_TYPE_REAL | 3)) return tb_false;
- if (!tb_stream_bwrit_double_bbe(writer->stream, tb_oc_number_double(object))) return tb_false;
- }
- break;
-#endif
- default:
- tb_assert_and_check_return_val(0, tb_false);
- break;
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_bplist_writer_func_boolean(tb_oc_bplist_writer_t* writer, tb_object_ref_t object, tb_size_t item_size)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream && object, tb_false);
-
- // writ it
- return tb_stream_bwrit_u8(writer->stream, TB_OBJECT_BPLIST_TYPE_NONE | (tb_oc_boolean_bool(object)? TB_OBJECT_BPLIST_TYPE_TRUE : TB_OBJECT_BPLIST_TYPE_FALSE));
-}
-static tb_bool_t tb_oc_bplist_writer_func_dictionary(tb_oc_bplist_writer_t* writer, tb_object_ref_t object, tb_size_t item_size)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream && object, tb_false);
-
- // index tables
- tb_byte_t* index_tables = (tb_byte_t*)tb_object_getp(object);
-
- // size
- tb_size_t size = tb_oc_dictionary_size(object);
- tb_assert_and_check_return_val(!size == !index_tables, tb_false);
-
- // writ flag
- tb_uint8_t flag = TB_OBJECT_BPLIST_TYPE_DICT | (size < 15 ? (tb_uint8_t)size : 0xf);
- if (!tb_stream_bwrit_u8(writer->stream, flag)) return tb_false;
-
- // writ size
- if (size >= 15)
- {
- // init osize
- tb_object_ref_t osize = tb_oc_bplist_writer_init_number(size);
- tb_assert_and_check_return_val(osize, tb_false);
-
- // writ it
- if (!tb_oc_bplist_writer_func_number(writer, osize, item_size))
- {
- tb_object_exit(osize);
- return tb_false;
- }
-
- // exit osize
- tb_object_exit(osize);
- }
-
- // writ index tables
- if (index_tables)
- {
- if (!tb_stream_bwrit(writer->stream, index_tables, (size << 1) * item_size)) return tb_false;
- }
-
- // ok
- return tb_true;
-}
-static tb_uint64_t tb_oc_bplist_writer_builder_maxn(tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return_val(object, 0);
-
- // walk
- tb_uint64_t size = 0;
- switch (tb_object_type(object))
- {
- case TB_OBJECT_TYPE_ARRAY:
- {
- // walk
- tb_for_all (tb_object_ref_t, item, tb_oc_array_itor(object))
- {
- if (item) size += tb_oc_bplist_writer_builder_maxn(item);
- }
- }
- break;
- case TB_OBJECT_TYPE_DICTIONARY:
- {
- // walk
- tb_for_all (tb_oc_dictionary_item_t*, item, tb_oc_dictionary_itor(object))
- {
- // item
- if (item && item->key && item->val)
- size += 1 + tb_oc_bplist_writer_builder_maxn(item->val);
- }
- }
- break;
- default:
- break;
- }
-
- return size + 1;
-}
-static tb_size_t tb_oc_bplist_writer_builder_addo(tb_object_ref_t object, tb_object_ref_t list, tb_hash_map_ref_t hash)
-{
- // check
- tb_assert_and_check_return_val(object && list && hash, 0);
-
- // the object index
- tb_size_t index = (tb_size_t)tb_hash_map_get(hash, object);
-
- // new object?
- if (!index)
- {
- // append object
- tb_oc_array_append(list, object);
-
- // index
- index = tb_oc_array_size(list);
-
- // set index
- tb_hash_map_insert(hash, object, (tb_pointer_t)index);
- tb_object_retain(object);
-
- // check
- tb_assert(!tb_object_getp(object));
- }
-
- // ok?
- return index;
-}
-static tb_void_t tb_oc_bplist_writer_builder_init(tb_object_ref_t object, tb_object_ref_t list, tb_hash_map_ref_t hash, tb_size_t item_size)
-{
- // check
- tb_assert_and_check_return(object && list && hash);
-
- // build items
- switch (tb_object_type(object))
- {
- case TB_OBJECT_TYPE_ARRAY:
- {
- // make index tables
- tb_byte_t* index_tables = tb_null;
- tb_size_t size = tb_oc_array_size(object);
- if (size)
- {
- index_tables = (tb_byte_t*)tb_object_getp(object);
- if (!index_tables)
- {
- // make it
- index_tables = tb_malloc0_bytes(size * item_size);
-
- // FIXME: not using the user private data
- tb_object_setp(object, index_tables);
- }
- }
-
- // walk
- tb_size_t i = 0;
- tb_for_all (tb_object_ref_t, item, tb_oc_array_itor(object))
- {
- // build item
- if (item)
- {
- // add item to builder
- tb_size_t index = tb_oc_bplist_writer_builder_addo(item, list, hash);
-
- // add index to tables
- if (index && index_tables) tb_oc_bplist_writer_bits_set(index_tables + i++ * item_size, index - 1, item_size);
-// tb_trace_d("item: %p[%lu]", index_tables, index - 1);
-
- // init next
- tb_oc_bplist_writer_builder_init(item, list, hash, item_size);
- }
- }
- }
- break;
- case TB_OBJECT_TYPE_DICTIONARY:
- {
- // make index tables
- tb_byte_t* index_tables = tb_null;
- tb_size_t size = tb_oc_dictionary_size(object);
- if (size)
- {
- index_tables = (tb_byte_t*)tb_object_getp(object);
- if (!index_tables)
- {
- // make it
- index_tables = tb_malloc0_bytes((size << 1) * item_size);
-
- // FIXME: not using the user private data
- tb_object_setp(object, index_tables);
- }
- }
-
- // walk keys
- {
- tb_size_t i = 0;
- tb_for_all (tb_oc_dictionary_item_t*, item, tb_oc_dictionary_itor(object))
- {
- // item
- if (item && item->key && item->val)
- {
- // make key object
- tb_object_ref_t key = tb_oc_string_init_from_cstr(item->key);
- if (key)
- {
- // add key to builder
- tb_size_t index = tb_oc_bplist_writer_builder_addo(key, list, hash);
-
- // add index to tables
- if (index && index_tables) tb_oc_bplist_writer_bits_set(index_tables + i++ * item_size, index - 1, item_size);
-// tb_trace_d("keys: %p[%lu]", index_tables, index - 1);
-
- // build key
- tb_oc_bplist_writer_builder_init(key, list, hash, item_size);
- tb_object_exit(key);
-
- }
- }
- }
- }
-
- // walk vals
- {
- tb_size_t i = 0;
- tb_for_all (tb_oc_dictionary_item_t*, item, tb_oc_dictionary_itor(object))
- {
- // item
- if (item && item->key && item->val)
- {
- // add val to builder
- tb_size_t index = tb_oc_bplist_writer_builder_addo(item->val, list, hash);
-
- // add index to tables
- if (index && index_tables) tb_oc_bplist_writer_bits_set(index_tables + (size + i++) * item_size, index - 1, item_size);
-// tb_trace_d("vals: %p[%lu]", index_tables, index - 1);
-
- // build val
- tb_oc_bplist_writer_builder_init(item->val, list, hash, item_size);
- }
- }
- }
- }
- break;
- default:
- break;
- }
-}
-static tb_void_t tb_oc_bplist_writer_builder_exit(tb_object_ref_t list, tb_hash_map_ref_t hash)
-{
- // exit hash
- if (hash)
- {
- // walk
- tb_for_all (tb_hash_map_item_ref_t, item, hash)
- {
- // exit item
- if (item && item->name)
- {
- tb_byte_t* priv = (tb_byte_t*)tb_object_getp((tb_object_ref_t)item->name);
- if (priv)
- {
- tb_free(priv);
- tb_object_setp((tb_object_ref_t)item->name, tb_null);
- }
-
- tb_object_exit((tb_object_ref_t)item->name);
- }
- }
-
- // exit it
- tb_hash_map_exit(hash);
- }
-
- // exit list
- if (list) tb_object_exit(list);
-}
-static tb_long_t tb_oc_bplist_writer_done(tb_stream_ref_t stream, tb_object_ref_t object, tb_bool_t deflate)
-{
- // check
- tb_assert_and_check_return_val(object && stream, -1);
-
- // done
- tb_bool_t ok = tb_false;
- tb_size_t i = 0;
- tb_byte_t pad[6] = {0};
- tb_object_ref_t list = tb_null;
- tb_hash_map_ref_t hash = tb_null;
- tb_size_t object_count = 0;
- tb_uint64_t object_maxn = 0;
- tb_uint64_t root_object = 0;
- tb_uint64_t offset_table_index = 0;
- tb_size_t offset_size = 0;
- tb_size_t item_size = 0;
- tb_uint64_t* offsets = tb_null;
- tb_hize_t bof = 0;
- tb_hize_t eof = 0;
- do
- {
- // init writer
- tb_oc_bplist_writer_t writer = {0};
- writer.stream = stream;
-
- // init list
- list = tb_oc_array_init(TB_OBJECT_BPLIST_LIST_GROW, tb_true);
- tb_assert_and_check_break(list);
-
- // init hash
- hash = tb_hash_map_init(0, tb_element_ptr(tb_null, tb_null), tb_element_uint32());
- tb_assert_and_check_break(hash);
-
- // object maxn
- object_maxn = tb_oc_bplist_writer_builder_maxn(object);
- item_size = tb_object_need_bytes(object_maxn);
- tb_trace_d("object_maxn: %llu", object_maxn);
- tb_trace_d("item_size: %lu", item_size);
-
- // add root object to builder
- tb_oc_bplist_writer_builder_addo(object, list, hash);
-
- // init object builder
- tb_oc_bplist_writer_builder_init(object, list, hash, item_size);
-
- // init object count
- object_count = tb_oc_array_size(list);
- tb_trace_d("object_count: %lu", object_count);
-
- // init offsets
- offsets = (tb_uint64_t*)tb_malloc0(object_count * sizeof(tb_uint64_t));
- tb_assert_and_check_break(offsets);
-
- // the begin offset
- bof = tb_stream_offset(stream);
-
- // writ magic & version
- if (!tb_stream_bwrit(stream, (tb_byte_t const*)"bplist00", 8)) break;
-
- // writ objects
- if (object_count)
- {
- i = 0;
- tb_bool_t failed = tb_false;
- tb_for_all_if (tb_object_ref_t, item, tb_oc_array_itor(list), item && !failed)
- {
- // check
- tb_assert_and_check_break_state(i < object_count, failed, tb_true);
-
- // save offset
- offsets[i++] = tb_stream_offset(stream);
-
- // the func
- tb_oc_bplist_writer_func_t func = tb_oc_bplist_writer_func(tb_object_type(item));
- tb_assert_and_check_continue(func);
-
- // writ object
- if (!func(&writer, item, item_size))
- {
- failed = tb_true;
- break;
- }
- }
-
- // failed?
- tb_check_break(!failed);
- }
-
- // offset table index
- offset_table_index = tb_stream_offset(stream);
- offset_size = tb_object_need_bytes(offset_table_index);
- tb_trace_d("offset_table_index: %llu", offset_table_index);
- tb_trace_d("offset_size: %lu", offset_size);
-
- // writ offset table
- tb_bool_t failed = tb_false;
- for (i = 0; !failed && i < object_count; i++)
- {
- switch (offset_size)
- {
- case 1:
- if (!tb_stream_bwrit_u8(stream, (tb_uint8_t)offsets[i])) failed = tb_true;
- break;
- case 2:
- if (!tb_stream_bwrit_u16_be(stream, (tb_uint16_t)offsets[i])) failed = tb_true;
- break;
- case 4:
- if (!tb_stream_bwrit_u32_be(stream, (tb_uint32_t)offsets[i])) failed = tb_true;
- break;
- case 8:
- if (!tb_stream_bwrit_u64_be(stream, (tb_uint64_t)offsets[i])) failed = tb_true;
- break;
- default:
- tb_assert_and_check_break_state(0, failed, tb_true);
- break;
- }
- }
-
- // failed?
- tb_check_break(!failed);
-
- // writ pad, like apple?
- if (!tb_stream_bwrit(stream, pad, 6)) break;
-
- // writ tail
- if (!tb_stream_bwrit_u8(stream, (tb_uint8_t)offset_size)) break;
- if (!tb_stream_bwrit_u8(stream, (tb_uint8_t)item_size)) break;
- if (!tb_stream_bwrit_u64_be(stream, object_count)) break;
- if (!tb_stream_bwrit_u64_be(stream, root_object)) break;
- if (!tb_stream_bwrit_u64_be(stream, offset_table_index)) break;
-
- // sync stream
- if (!tb_stream_sync(stream, tb_true)) break;
-
- // the end offset
- eof = tb_stream_offset(stream);
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // exit offsets
- if (offsets) tb_free(offsets);
- offsets = tb_null;
-
- // exit object builder
- tb_oc_bplist_writer_builder_exit(list, hash);
- list = tb_null;
- hash = tb_null;
-
- // ok?
- return (ok && (eof >= bof))? (tb_long_t)(eof - bof) : -1;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-tb_oc_writer_t* tb_oc_bplist_writer()
-{
- // the writer
- static tb_oc_writer_t s_writer = {0};
-
- // init writer
- s_writer.writ = tb_oc_bplist_writer_done;
-
- // init hooker
- s_writer.hooker = tb_hash_map_init(TB_HASH_MAP_BUCKET_SIZE_MICRO, tb_element_uint32(), tb_element_ptr(tb_null, tb_null));
- tb_assert_and_check_return_val(s_writer.hooker, tb_null);
-
- // hook writer
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_DATE, tb_oc_bplist_writer_func_date);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_DATA, tb_oc_bplist_writer_func_data);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_ARRAY, tb_oc_bplist_writer_func_array);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_STRING, tb_oc_bplist_writer_func_string);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_NUMBER, tb_oc_bplist_writer_func_number);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_BOOLEAN, tb_oc_bplist_writer_func_boolean);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_DICTIONARY, tb_oc_bplist_writer_func_dictionary);
-
- // ok
- return &s_writer;
-}
-tb_bool_t tb_oc_bplist_writer_hook(tb_size_t type, tb_oc_bplist_writer_func_t func)
-{
- // check
- tb_assert_and_check_return_val(func, tb_false);
-
- // the writer
- tb_oc_writer_t* writer = tb_oc_writer_get(TB_OBJECT_FORMAT_BPLIST);
- tb_assert_and_check_return_val(writer && writer->hooker, tb_false);
-
- // hook it
- tb_hash_map_insert(writer->hooker, (tb_pointer_t)type, func);
-
- // ok
- return tb_true;
-}
-tb_oc_bplist_writer_func_t tb_oc_bplist_writer_func(tb_size_t type)
-{
- // the writer
- tb_oc_writer_t* writer = tb_oc_writer_get(TB_OBJECT_FORMAT_BPLIST);
- tb_assert_and_check_return_val(writer && writer->hooker, tb_null);
-
- // the func
- return (tb_oc_bplist_writer_func_t)tb_hash_map_get(writer->hooker, (tb_pointer_t)type);
-}
-
diff --git a/core/src/tbox/src/tbox/object/impl/writer/bplist.h b/core/src/tbox/src/tbox/object/impl/writer/bplist.h
deleted file mode 100644
index 83c316541..000000000
--- a/core/src/tbox/src/tbox/object/impl/writer/bplist.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file bplist.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_IMPL_WRITER_BPLIST_H
-#define TB_OBJECT_IMPL_WRITER_BPLIST_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the object bplist writer type
-typedef struct __tb_oc_bplist_writer_t
-{
- /// the stream
- tb_stream_ref_t stream;
-
-}tb_oc_bplist_writer_t;
-
-/// the bplist writer func type
-typedef tb_bool_t (*tb_oc_bplist_writer_func_t)(tb_oc_bplist_writer_t* writer, tb_object_ref_t object, tb_size_t item_size);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! the bplist object writer
- *
- * @return the bplist object writer
- */
-tb_oc_writer_t* tb_oc_bplist_writer(tb_noarg_t);
-
-/*! hook the bplist writer
- *
- * @param type the object type
- * @param func the writer func
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_bplist_writer_hook(tb_size_t type, tb_oc_bplist_writer_func_t func);
-
-/*! the bplist writer func
- *
- * @param type the object type
- *
- * @return the object writer func
- */
-tb_oc_bplist_writer_func_t tb_oc_bplist_writer_func(tb_size_t type);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/impl/writer/json.c b/core/src/tbox/src/tbox/object/impl/writer/json.c
deleted file mode 100644
index 80f8b46e8..000000000
--- a/core/src/tbox/src/tbox/object/impl/writer/json.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file json.c
- * @ingroup object
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "oc_writer_json"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "json.h"
-#include "writer.h"
-#include "../../../algorithm/algorithm.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static tb_bool_t tb_oc_json_writer_func_null(tb_oc_json_writer_t* writer, tb_object_ref_t object, tb_size_t level)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream, tb_false);
-
- // writ
- if (tb_stream_printf(writer->stream, "null") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_json_writer_func_array(tb_oc_json_writer_t* writer, tb_object_ref_t object, tb_size_t level)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream, tb_false);
-
- // writ
- if (tb_oc_array_size(object))
- {
- // writ beg
- if (tb_stream_printf(writer->stream, "[") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
-
- // walk
- tb_for_all (tb_object_ref_t, item, tb_oc_array_itor(object))
- {
- // item
- if (item)
- {
- // func
- tb_oc_json_writer_func_t func = tb_oc_json_writer_func(item->type);
- tb_assert_and_check_continue(func);
-
- // writ tab
- if (item_itor != item_head)
- {
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, ",") < 0) return tb_false;
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, 1)) return tb_false;
- }
- else if (!tb_oc_writer_tab(writer->stream, writer->deflate, level + 1)) return tb_false;
-
- // writ
- if (!func(writer, item, level + 1)) return tb_false;
- }
- }
-
- // writ end
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "]") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- }
- else
- {
- if (tb_stream_printf(writer->stream, "[]") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_json_writer_func_string(tb_oc_json_writer_t* writer, tb_object_ref_t object, tb_size_t level)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream, tb_false);
-
- // writ
- if (tb_oc_string_size(object))
- {
- if (tb_stream_printf(writer->stream, "\"%s\"", tb_oc_string_cstr(object)) < 0) return tb_false;
- }
- else if (tb_stream_printf(writer->stream, "\"\"") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_json_writer_func_number(tb_oc_json_writer_t* writer, tb_object_ref_t object, tb_size_t level)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream, tb_false);
-
- // writ
- switch (tb_oc_number_type(object))
- {
- case TB_OC_NUMBER_TYPE_UINT64:
- if (tb_stream_printf(writer->stream, "%llu", tb_oc_number_uint64(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_SINT64:
- if (tb_stream_printf(writer->stream, "%lld", tb_oc_number_sint64(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_UINT32:
- if (tb_stream_printf(writer->stream, "%u", tb_oc_number_uint32(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_SINT32:
- if (tb_stream_printf(writer->stream, "%d", tb_oc_number_sint32(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_UINT16:
- if (tb_stream_printf(writer->stream, "%u", tb_oc_number_uint16(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_SINT16:
- if (tb_stream_printf(writer->stream, "%d", tb_oc_number_sint16(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_UINT8:
- if (tb_stream_printf(writer->stream, "%u", tb_oc_number_uint8(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_SINT8:
- if (tb_stream_printf(writer->stream, "%d", tb_oc_number_sint8(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- case TB_OC_NUMBER_TYPE_FLOAT:
- if (tb_stream_printf(writer->stream, "%f", tb_oc_number_float(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_DOUBLE:
- if (tb_stream_printf(writer->stream, "%lf", tb_oc_number_double(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
-#endif
- default:
- break;
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_json_writer_func_boolean(tb_oc_json_writer_t* writer, tb_object_ref_t object, tb_size_t level)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream, tb_false);
-
- // writ
- if (tb_stream_printf(writer->stream, "%s", tb_oc_boolean_bool(object)? "true" : "false") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_json_writer_func_dictionary(tb_oc_json_writer_t* writer, tb_object_ref_t object, tb_size_t level)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream, tb_false);
-
- // writ
- if (tb_oc_dictionary_size(object))
- {
- // writ beg
- if (tb_stream_printf(writer->stream, "{") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
-
- // walk
- tb_for_all (tb_oc_dictionary_item_t*, item, tb_oc_dictionary_itor(object))
- {
- // item
- if (item && item->key && item->val)
- {
- // func
- tb_oc_json_writer_func_t func = tb_oc_json_writer_func(item->val->type);
- tb_assert_and_check_continue(func);
-
- // writ tab
- if (item_itor != item_head)
- {
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, ",") < 0) return tb_false;
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, 1)) return tb_false;
- }
- else if (!tb_oc_writer_tab(writer->stream, writer->deflate, level + 1)) return tb_false;
-
- // writ key
- if (tb_stream_printf(writer->stream, "\"%s\":", item->key) < 0) return tb_false;
-
- // writ spaces
- if (!writer->deflate) if (tb_stream_printf(writer->stream, " ") < 0) return tb_false;
- if (item->val->type == TB_OBJECT_TYPE_DICTIONARY || item->val->type == TB_OBJECT_TYPE_ARRAY)
- {
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level + 1)) return tb_false;
- }
-
- // writ val
- if (!func(writer, item->val, level + 1)) return tb_false;
- }
- }
-
- // writ end
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "}") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- }
- else
- {
- if (tb_stream_printf(writer->stream, "{}") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- }
-
- // ok
- return tb_true;
-}
-static tb_long_t tb_oc_json_writer_done(tb_stream_ref_t stream, tb_object_ref_t object, tb_bool_t deflate)
-{
- // check
- tb_assert_and_check_return_val(object && stream, -1);
-
- // init writer
- tb_oc_json_writer_t writer = {0};
- writer.stream = stream;
- writer.deflate = deflate;
-
- // func
- tb_oc_json_writer_func_t func = tb_oc_json_writer_func(object->type);
- tb_assert_and_check_return_val(func, tb_false);
-
- // the begin offset
- tb_hize_t bof = tb_stream_offset(stream);
-
- // writ
- if (!func(&writer, object, 0)) return -1;
-
- // sync
- if (!tb_stream_sync(stream, tb_true)) return -1;
-
- // the end offset
- tb_hize_t eof = tb_stream_offset(stream);
-
- // ok?
- return eof >= bof? (tb_long_t)(eof - bof) : -1;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-tb_oc_writer_t* tb_oc_json_writer()
-{
- // the writer
- static tb_oc_writer_t s_writer = {0};
-
- // init writer
- s_writer.writ = tb_oc_json_writer_done;
-
- // init hooker
- s_writer.hooker = tb_hash_map_init(TB_HASH_MAP_BUCKET_SIZE_MICRO, tb_element_uint32(), tb_element_ptr(tb_null, tb_null));
- tb_assert_and_check_return_val(s_writer.hooker, tb_null);
-
- // hook writer
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_NULL, tb_oc_json_writer_func_null);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_ARRAY, tb_oc_json_writer_func_array);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_STRING, tb_oc_json_writer_func_string);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_NUMBER, tb_oc_json_writer_func_number);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_BOOLEAN, tb_oc_json_writer_func_boolean);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_DICTIONARY, tb_oc_json_writer_func_dictionary);
-
- // ok
- return &s_writer;
-}
-tb_bool_t tb_oc_json_writer_hook(tb_size_t type, tb_oc_json_writer_func_t func)
-{
- // check
- tb_assert_and_check_return_val(func, tb_false);
-
- // the writer
- tb_oc_writer_t* writer = tb_oc_writer_get(TB_OBJECT_FORMAT_JSON);
- tb_assert_and_check_return_val(writer && writer->hooker, tb_false);
-
- // hook it
- tb_hash_map_insert(writer->hooker, (tb_pointer_t)type, func);
-
- // ok
- return tb_true;
-}
-tb_oc_json_writer_func_t tb_oc_json_writer_func(tb_size_t type)
-{
- // the writer
- tb_oc_writer_t* writer = tb_oc_writer_get(TB_OBJECT_FORMAT_JSON);
- tb_assert_and_check_return_val(writer && writer->hooker, tb_null);
-
- // the func
- return (tb_oc_json_writer_func_t)tb_hash_map_get(writer->hooker, (tb_pointer_t)type);
-}
-
diff --git a/core/src/tbox/src/tbox/object/impl/writer/json.h b/core/src/tbox/src/tbox/object/impl/writer/json.h
deleted file mode 100644
index 2abd7dd49..000000000
--- a/core/src/tbox/src/tbox/object/impl/writer/json.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file json.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_IMPL_WRITER_JSON_H
-#define TB_OBJECT_IMPL_WRITER_JSON_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the object json writer type
-typedef struct __tb_oc_json_writer_t
-{
- /// the stream
- tb_stream_ref_t stream;
-
- /// is deflate?
- tb_bool_t deflate;
-
-}tb_oc_json_writer_t;
-
-/// the json writer func type
-typedef tb_bool_t (*tb_oc_json_writer_func_t)(tb_oc_json_writer_t* writer, tb_object_ref_t object, tb_size_t level);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! the json object writer
- *
- * @return the json object writer
- */
-tb_oc_writer_t* tb_oc_json_writer(tb_noarg_t);
-
-/*! hook the json writer
- *
- * @param type the object type
- * @param func the writer func
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_json_writer_hook(tb_size_t type, tb_oc_json_writer_func_t func);
-
-/*! the json writer func
- *
- * @param type the object type
- *
- * @return the object writer func
- */
-tb_oc_json_writer_func_t tb_oc_json_writer_func(tb_size_t type);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/impl/writer/prefix.h b/core/src/tbox/src/tbox/object/impl/writer/prefix.h
deleted file mode 100644
index c383641cc..000000000
--- a/core/src/tbox/src/tbox/object/impl/writer/prefix.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file prefix.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_WRITER_PREFIX_H
-#define TB_OBJECT_WRITER_PREFIX_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "../prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * inlines
- */
-static __tb_inline__ tb_bool_t tb_oc_writer_tab(tb_stream_ref_t stream, tb_bool_t deflate, tb_size_t tab)
-{
- // writ tab
- if (!deflate)
- {
- while (tab--) if (tb_stream_printf(stream, " ") < 0) return tb_false;
- }
-
- // ok
- return tb_true;
-}
-static __tb_inline__ tb_bool_t tb_oc_writer_newline(tb_stream_ref_t stream, tb_bool_t deflate)
-{
- // writ newline
- if (!deflate && tb_stream_printf(stream, __tb_newline__) < 0) return tb_false;
-
- // ok
- return tb_true;
-}
-static __tb_inline__ tb_bool_t tb_oc_writer_bin_type_size(tb_stream_ref_t stream, tb_size_t type, tb_uint64_t size)
-{
- // check
- tb_assert_and_check_return_val(stream && type <= 0xff, tb_false);
-
- // byte for size < 64bits
- tb_size_t sizeb = tb_object_need_bytes(size);
- tb_assert_and_check_return_val(sizeb <= 8, tb_false);
-
- // flag for size
- tb_size_t sizef = 0;
- switch (sizeb)
- {
- case 1: sizef = 0xc; break;
- case 2: sizef = 0xd; break;
- case 4: sizef = 0xe; break;
- case 8: sizef = 0xf; break;
- default: break;
- }
- tb_assert_and_check_return_val(sizef, tb_false);
-
- // writ flag
- tb_uint8_t flag = ((type < 0xf? (tb_uint8_t)type : 0xf) << 4) | (size < 0xc? (tb_uint8_t)size : (tb_uint8_t)sizef);
- if (!tb_stream_bwrit_u8(stream, flag)) return tb_false;
-
- // trace
-// tb_trace("writ: type: %lu, size: %llu", type, size);
-
- // writ type
- if (type >= 0xf) if (!tb_stream_bwrit_u8(stream, (tb_uint8_t)type)) return tb_false;
-
- // writ size
- if (size >= 0xc)
- {
- switch (sizeb)
- {
- case 1:
- if (!tb_stream_bwrit_u8(stream, (tb_uint8_t)size)) return tb_false;
- break;
- case 2:
- if (!tb_stream_bwrit_u16_be(stream, (tb_uint16_t)size)) return tb_false;
- break;
- case 4:
- if (!tb_stream_bwrit_u32_be(stream, (tb_uint32_t)size)) return tb_false;
- break;
- case 8:
- if (!tb_stream_bwrit_u64_be(stream, (tb_uint64_t)size)) return tb_false;
- break;
- default:
- tb_assert_and_check_return_val(0, tb_false);
- break;
- }
- }
-
- // ok
- return tb_true;
-}
-
-#endif
diff --git a/core/src/tbox/src/tbox/object/impl/writer/writer.c b/core/src/tbox/src/tbox/object/impl/writer/writer.c
deleted file mode 100644
index f3e96a5c3..000000000
--- a/core/src/tbox/src/tbox/object/impl/writer/writer.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file writer.c
- * @ingroup object
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "writer.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * globals
- */
-
-// the object writer
-static tb_oc_writer_t* g_writer[TB_OBJECT_FORMAT_MAXN] = {tb_null};
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_bool_t tb_oc_writer_set(tb_size_t format, tb_oc_writer_t* writer)
-{
- // check
- format &= 0x00ff;
- tb_assert_and_check_return_val(writer && (format < tb_arrayn(g_writer)), tb_false);
-
- // exit the older writer if exists
- tb_oc_writer_remove(format);
-
- // set
- g_writer[format] = writer;
-
- // ok
- return tb_true;
-}
-tb_void_t tb_oc_writer_remove(tb_size_t format)
-{
- // check
- format &= 0x00ff;
- tb_assert_and_check_return((format < tb_arrayn(g_writer)));
-
- // exit it
- if (g_writer[format])
- {
- // exit hooker
- if (g_writer[format]->hooker) tb_hash_map_exit(g_writer[format]->hooker);
- g_writer[format]->hooker = tb_null;
-
- // clear it
- g_writer[format] = tb_null;
- }
-}
-tb_oc_writer_t* tb_oc_writer_get(tb_size_t format)
-{
- // check
- format &= 0x00ff;
- tb_assert_and_check_return_val((format < tb_arrayn(g_writer)), tb_null);
-
- // ok
- return g_writer[format];
-}
-tb_long_t tb_oc_writer_done(tb_object_ref_t object, tb_stream_ref_t stream, tb_size_t format)
-{
- // check
- tb_assert_and_check_return_val(object && stream, -1);
-
- // the writer
- tb_oc_writer_t* writer = tb_oc_writer_get(format);
- tb_assert_and_check_return_val(writer && writer->writ, -1);
-
- // writ it
- return writer->writ(stream, object, (format & TB_OBJECT_FORMAT_DEFLATE)? tb_true : tb_false);
-}
diff --git a/core/src/tbox/src/tbox/object/impl/writer/writer.h b/core/src/tbox/src/tbox/object/impl/writer/writer.h
deleted file mode 100644
index 628297da9..000000000
--- a/core/src/tbox/src/tbox/object/impl/writer/writer.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file writer.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_IMPL_WRITER_H
-#define TB_OBJECT_IMPL_WRITER_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "xml.h"
-#include "bin.h"
-#include "json.h"
-#include "xplist.h"
-#include "bplist.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! set object writer
- *
- * @param format the writer format
- * @param writer the writer
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_writer_set(tb_size_t format, tb_oc_writer_t* writer);
-
-/*! get object writer
- *
- * @param format the writer format
- *
- * @return the object writer
- */
-tb_oc_writer_t* tb_oc_writer_get(tb_size_t format);
-
-/*! remove object writer
- *
- * @param format the writer format
- */
-tb_void_t tb_oc_writer_remove(tb_size_t format);
-
-/*! done writer
- *
- * @param object the object
- * @param stream the stream
- * @param format the object format
- *
- * @return the writed size, failed: -1
- */
-tb_long_t tb_oc_writer_done(tb_object_ref_t object, tb_stream_ref_t stream, tb_size_t format);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-
-#endif
diff --git a/core/src/tbox/src/tbox/object/impl/writer/xml.c b/core/src/tbox/src/tbox/object/impl/writer/xml.c
deleted file mode 100644
index a75132d24..000000000
--- a/core/src/tbox/src/tbox/object/impl/writer/xml.c
+++ /dev/null
@@ -1,432 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file xml.c
- * @ingroup object
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "oc_writer_xml"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "xml.h"
-#include "writer.h"
-#include "../../../algorithm/algorithm.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static tb_bool_t tb_oc_xml_writer_func_null(tb_oc_xml_writer_t* writer, tb_object_ref_t object, tb_size_t level)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream, tb_false);
-
- // writ
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<null/>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_xml_writer_func_date(tb_oc_xml_writer_t* writer, tb_object_ref_t object, tb_size_t level)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream, tb_false);
-
- // no empty?
- tb_time_t time = tb_oc_date_time(object);
- if (time > 0)
- {
- // writ beg
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<date>") < 0) return tb_false;
-
- // writ date
- tb_tm_t date = {0};
- if (tb_localtime(time, &date))
- {
- if (tb_stream_printf(writer->stream, "%04ld-%02ld-%02ld %02ld:%02ld:%02ld"
- , date.year
- , date.month
- , date.mday
- , date.hour
- , date.minute
- , date.second) < 0) return tb_false;
- }
-
- // writ end
- if (tb_stream_printf(writer->stream, "</date>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- }
- else
- {
- // writ
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<date/>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_xml_writer_func_data(tb_oc_xml_writer_t* writer, tb_object_ref_t object, tb_size_t level)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream, tb_false);
-
- // no empty?
- if (tb_oc_data_size(object))
- {
- // writ beg
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<data>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
-
- // decode base64 data
- tb_byte_t const* ib = (tb_byte_t const*)tb_oc_data_getp(object);
- tb_size_t in = tb_oc_data_size(object);
- tb_size_t on = in << 1;
- tb_char_t* ob = tb_malloc0_cstr(on);
- tb_assert_and_check_return_val(ob && on, tb_false);
- on = tb_base64_encode(ib, in, ob, on);
- tb_trace_d("base64: %u => %u", in, on);
-
- // writ data
- tb_char_t const* p = ob;
- tb_char_t const* e = ob + on;
- tb_size_t n = 0;
- for (; p < e && *p; p++, n++)
- {
- if (!(n & 63))
- {
- if (n) if (!tb_oc_writer_newline(writer->stream, writer->deflate)) break;
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) break;
- }
- if (tb_stream_printf(writer->stream, "%c", *p) < 0) break;
- }
-
- // free the data
- tb_free(ob);
-
- // check
- tb_check_return_val(p == e, tb_false);
-
- // writ newline
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
-
- // writ end
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "</data>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- }
- else
- {
- // writ
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<data/>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_xml_writer_func_array(tb_oc_xml_writer_t* writer, tb_object_ref_t object, tb_size_t level)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream, tb_false);
-
- // writ
- if (tb_oc_array_size(object))
- {
- // writ beg
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<array>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
-
- // walk
- tb_for_all (tb_object_ref_t, item, tb_oc_array_itor(object))
- {
- // item
- if (item)
- {
- // func
- tb_oc_xml_writer_func_t func = tb_oc_xml_writer_func(item->type);
- tb_assert_and_check_continue(func);
-
- // writ
- if (!func(writer, item, level + 1)) return tb_false;
- }
- }
-
- // writ end
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "</array>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- }
- else
- {
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<array/>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_xml_writer_func_string(tb_oc_xml_writer_t* writer, tb_object_ref_t object, tb_size_t level)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream, tb_false);
-
- // writ
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_oc_string_size(object))
- {
- if (tb_stream_printf(writer->stream, "<string>%s</string>", tb_oc_string_cstr(object)) < 0) return tb_false;
- }
- else if (tb_stream_printf(writer->stream, "<string/>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_xml_writer_func_number(tb_oc_xml_writer_t* writer, tb_object_ref_t object, tb_size_t level)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream, tb_false);
-
- // writ
- switch (tb_oc_number_type(object))
- {
- case TB_OC_NUMBER_TYPE_UINT64:
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<number>%llu</number>", tb_oc_number_uint64(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_SINT64:
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<number>%lld</number>", tb_oc_number_sint64(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_UINT32:
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<number>%u</number>", tb_oc_number_uint32(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_SINT32:
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<number>%d</number>", tb_oc_number_sint32(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_UINT16:
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<number>%u</number>", tb_oc_number_uint16(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_SINT16:
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<number>%d</number>", tb_oc_number_sint16(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_UINT8:
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<number>%u</number>", tb_oc_number_uint8(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_SINT8:
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<number>%d</number>", tb_oc_number_sint8(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- case TB_OC_NUMBER_TYPE_FLOAT:
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<number>%f</number>", tb_oc_number_float(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_DOUBLE:
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<number>%lf</number>", tb_oc_number_double(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
-#endif
- default:
- break;
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_xml_writer_func_boolean(tb_oc_xml_writer_t* writer, tb_object_ref_t object, tb_size_t level)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream, tb_false);
-
- // writ
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<%s/>", tb_oc_boolean_bool(object)? "true" : "false") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_xml_writer_func_dictionary(tb_oc_xml_writer_t* writer, tb_object_ref_t object, tb_size_t level)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream, tb_false);
-
- // writ
- if (tb_oc_dictionary_size(object))
- {
- // writ beg
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<dict>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
-
- // walk
- tb_for_all (tb_oc_dictionary_item_t*, item, tb_oc_dictionary_itor(object))
- {
- // item
- if (item && item->key && item->val)
- {
- // func
- tb_oc_xml_writer_func_t func = tb_oc_xml_writer_func(item->val->type);
- tb_assert_and_check_continue(func);
-
- // writ key
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level + 1)) return tb_false;
- if (tb_stream_printf(writer->stream, "<key>%s</key>", item->key) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
-
- // writ val
- if (!func(writer, item->val, level + 1)) return tb_false;
- }
- }
-
- // writ end
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "</dict>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- }
- else
- {
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<dict/>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- }
-
- // ok
- return tb_true;
-}
-static tb_long_t tb_oc_xml_writer_done(tb_stream_ref_t stream, tb_object_ref_t object, tb_bool_t deflate)
-{
- // check
- tb_assert_and_check_return_val(object && stream, -1);
-
- // init writer
- tb_oc_xml_writer_t writer = {0};
- writer.stream = stream;
- writer.deflate = deflate;
-
- // func
- tb_oc_xml_writer_func_t func = tb_oc_xml_writer_func(object->type);
- tb_assert_and_check_return_val(func, -1);
-
- // the begin offset
- tb_hize_t bof = tb_stream_offset(stream);
-
- // writ xml header
- if (tb_stream_printf(stream, "<?xml version=\"2.0\" encoding=\"utf-8\"?>") < 0) return -1;
- if (!tb_oc_writer_newline(stream, deflate)) return -1;
-
- // writ
- if (!func(&writer, object, 0)) return -1;
-
- // sync
- if (!tb_stream_sync(stream, tb_true)) return -1;
-
- // the end offset
- tb_hize_t eof = tb_stream_offset(stream);
-
- // ok?
- return eof >= bof? (tb_long_t)(eof - bof) : -1;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-tb_oc_writer_t* tb_oc_xml_writer()
-{
- // the writer
- static tb_oc_writer_t s_writer = {0};
-
- // init writer
- s_writer.writ = tb_oc_xml_writer_done;
-
- // init hooker
- s_writer.hooker = tb_hash_map_init(TB_HASH_MAP_BUCKET_SIZE_MICRO, tb_element_uint32(), tb_element_ptr(tb_null, tb_null));
- tb_assert_and_check_return_val(s_writer.hooker, tb_null);
-
- // hook writer
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_NULL, tb_oc_xml_writer_func_null);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_DATE, tb_oc_xml_writer_func_date);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_DATA, tb_oc_xml_writer_func_data);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_ARRAY, tb_oc_xml_writer_func_array);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_STRING, tb_oc_xml_writer_func_string);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_NUMBER, tb_oc_xml_writer_func_number);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_BOOLEAN, tb_oc_xml_writer_func_boolean);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_DICTIONARY, tb_oc_xml_writer_func_dictionary);
-
- // ok
- return &s_writer;
-}
-tb_bool_t tb_oc_xml_writer_hook(tb_size_t type, tb_oc_xml_writer_func_t func)
-{
- // check
- tb_assert_and_check_return_val(func, tb_false);
-
- // the writer
- tb_oc_writer_t* writer = tb_oc_writer_get(TB_OBJECT_FORMAT_XML);
- tb_assert_and_check_return_val(writer && writer->hooker, tb_false);
-
- // hook it
- tb_hash_map_insert(writer->hooker, (tb_pointer_t)type, func);
-
- // ok
- return tb_true;
-}
-tb_oc_xml_writer_func_t tb_oc_xml_writer_func(tb_size_t type)
-{
- // the writer
- tb_oc_writer_t* writer = tb_oc_writer_get(TB_OBJECT_FORMAT_XML);
- tb_assert_and_check_return_val(writer && writer->hooker, tb_null);
-
- // the func
- return (tb_oc_xml_writer_func_t)tb_hash_map_get(writer->hooker, (tb_pointer_t)type);
-}
-
diff --git a/core/src/tbox/src/tbox/object/impl/writer/xml.h b/core/src/tbox/src/tbox/object/impl/writer/xml.h
deleted file mode 100644
index 11fd3f703..000000000
--- a/core/src/tbox/src/tbox/object/impl/writer/xml.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file xml.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_IMPL_WRITER_XML_H
-#define TB_OBJECT_IMPL_WRITER_XML_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the object xml writer type
-typedef struct __tb_oc_xml_writer_t
-{
- /// the stream
- tb_stream_ref_t stream;
-
- /// is deflate?
- tb_bool_t deflate;
-
-}tb_oc_xml_writer_t;
-
-/// the xml writer func type
-typedef tb_bool_t (*tb_oc_xml_writer_func_t)(tb_oc_xml_writer_t* writer, tb_object_ref_t object, tb_size_t level);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! the xml object writer
- *
- * @return the xml object writer
- */
-tb_oc_writer_t* tb_oc_xml_writer(tb_noarg_t);
-
-/*! hook the xml writer
- *
- * @param type the object type
- * @param func the writer func
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_xml_writer_hook(tb_size_t type, tb_oc_xml_writer_func_t func);
-
-/*! the xml writer func
- *
- * @param type the object type
- *
- * @return the object writer func
- */
-tb_oc_xml_writer_func_t tb_oc_xml_writer_func(tb_size_t type);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/impl/writer/xplist.c b/core/src/tbox/src/tbox/object/impl/writer/xplist.c
deleted file mode 100644
index bf02e8d9b..000000000
--- a/core/src/tbox/src/tbox/object/impl/writer/xplist.c
+++ /dev/null
@@ -1,425 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file xplist.c
- * @ingroup object
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "oc_writer_xplist"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "xplist.h"
-#include "writer.h"
-#include "../../../algorithm/algorithm.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static tb_bool_t tb_oc_xplist_writer_func_date(tb_oc_xplist_writer_t* writer, tb_object_ref_t object, tb_size_t level)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream, tb_false);
-
- // no empty?
- tb_time_t time = tb_oc_date_time(object);
- if (time > 0)
- {
- // writ beg
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<date>") < 0) return tb_false;
-
- // writ date
- tb_tm_t date = {0};
- if (tb_localtime(time, &date))
- {
- if (tb_stream_printf(writer->stream, "%04ld-%02ld-%02ldT%02ld:%02ld:%02ldZ"
- , date.year
- , date.month
- , date.mday
- , date.hour
- , date.minute
- , date.second) < 0) return tb_false;
- }
-
- // writ end
- if (tb_stream_printf(writer->stream, "</date>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- }
- else
- {
- // writ
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<date/>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_xplist_writer_func_data(tb_oc_xplist_writer_t* writer, tb_object_ref_t object, tb_size_t level)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream, tb_false);
-
- // no empty?
- if (tb_oc_data_size(object))
- {
- // writ beg
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<data>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
-
- // decode base64 data
- tb_byte_t const* ib = (tb_byte_t const*)tb_oc_data_getp(object);
- tb_size_t in = tb_oc_data_size(object);
- tb_size_t on = in << 1;
- tb_char_t* ob = tb_malloc0_cstr(on);
- tb_assert_and_check_return_val(ob && on, tb_false);
- on = tb_base64_encode(ib, in, ob, on);
- tb_trace_d("base64: %u => %u", in, on);
-
- // writ data
- tb_char_t const* p = ob;
- tb_char_t const* e = ob + on;
- tb_size_t n = 0;
- for (; p < e && *p; p++, n++)
- {
- if (!(n % 68))
- {
- if (n) if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- }
- if (tb_stream_printf(writer->stream, "%c", *p) < 0) return tb_false;
- }
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
-
- // free it
- tb_free(ob);
-
- // writ end
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "</data>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- }
- else
- {
- // writ
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<data>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
-
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "</data>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_xplist_writer_func_array(tb_oc_xplist_writer_t* writer, tb_object_ref_t object, tb_size_t level)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream, tb_false);
-
- // writ
- if (tb_oc_array_size(object))
- {
- // writ beg
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<array>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
-
- // walk
- tb_for_all (tb_object_ref_t, item, tb_oc_array_itor(object))
- {
- // item
- if (item)
- {
- // func
- tb_oc_xplist_writer_func_t func = tb_oc_xplist_writer_func(item->type);
- tb_assert_and_check_continue(func);
-
- // writ
- if (!func(writer, item, level + 1)) return tb_false;
- }
- }
-
- // writ end
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "</array>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- }
- else
- {
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<array/>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_xplist_writer_func_string(tb_oc_xplist_writer_t* writer, tb_object_ref_t object, tb_size_t level)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream, tb_false);
-
- // writ
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_oc_string_size(object))
- {
- if (tb_stream_printf(writer->stream, "<string>%s</string>", tb_oc_string_cstr(object)) < 0) return tb_false;
- }
- else if (tb_stream_printf(writer->stream, "<string/>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_xplist_writer_func_number(tb_oc_xplist_writer_t* writer, tb_object_ref_t object, tb_size_t level)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream, tb_false);
-
- // writ
- switch (tb_oc_number_type(object))
- {
- case TB_OC_NUMBER_TYPE_UINT64:
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<integer>%llu</integer>", tb_oc_number_uint64(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_SINT64:
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<integer>%lld</integer>", tb_oc_number_sint64(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_UINT32:
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<integer>%u</integer>", tb_oc_number_uint32(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_SINT32:
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<integer>%d</integer>", tb_oc_number_sint32(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_UINT16:
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<integer>%u</integer>", tb_oc_number_uint16(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_SINT16:
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<integer>%d</integer>", tb_oc_number_sint16(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_UINT8:
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<integer>%u</integer>", tb_oc_number_uint8(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_SINT8:
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<integer>%d</integer>", tb_oc_number_sint8(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- case TB_OC_NUMBER_TYPE_FLOAT:
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<real>%f</real>", tb_oc_number_float(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
- case TB_OC_NUMBER_TYPE_DOUBLE:
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<real>%lf</real>", tb_oc_number_double(object)) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- break;
-#endif
- default:
- break;
- }
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_xplist_writer_func_boolean(tb_oc_xplist_writer_t* writer, tb_object_ref_t object, tb_size_t level)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream, tb_false);
-
- // writ
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<%s/>", tb_oc_boolean_bool(object)? "true" : "false") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
-
- // ok
- return tb_true;
-}
-static tb_bool_t tb_oc_xplist_writer_func_dictionary(tb_oc_xplist_writer_t* writer, tb_object_ref_t object, tb_size_t level)
-{
- // check
- tb_assert_and_check_return_val(writer && writer->stream, tb_false);
-
- // writ
- if (tb_oc_dictionary_size(object))
- {
- // writ beg
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<dict>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
-
- // walk
- tb_for_all (tb_oc_dictionary_item_t*, item, tb_oc_dictionary_itor(object))
- {
- // item
- if (item && item->key && item->val)
- {
- // func
- tb_oc_xplist_writer_func_t func = tb_oc_xplist_writer_func(item->val->type);
- tb_assert_and_check_continue(func);
-
- // writ key
- tb_oc_writer_tab(writer->stream, writer->deflate, level + 1);
- if (tb_stream_printf(writer->stream, "<key>%s</key>", item->key) < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
-
- // writ val
- if (!func(writer, item->val, level + 1)) return tb_false;
- }
- }
-
- // writ end
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "</dict>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- }
- else
- {
- if (!tb_oc_writer_tab(writer->stream, writer->deflate, level)) return tb_false;
- if (tb_stream_printf(writer->stream, "<dict/>") < 0) return tb_false;
- if (!tb_oc_writer_newline(writer->stream, writer->deflate)) return tb_false;
- }
-
- // ok
- return tb_true;
-}
-static tb_long_t tb_oc_xplist_writer_done(tb_stream_ref_t stream, tb_object_ref_t object, tb_bool_t deflate)
-{
- // check
- tb_assert_and_check_return_val(object && stream, -1);
-
- // init writer
- tb_oc_xplist_writer_t writer = {0};
- writer.stream = stream;
- writer.deflate = deflate;
-
- // func
- tb_oc_xplist_writer_func_t func = tb_oc_xplist_writer_func(object->type);
- tb_assert_and_check_return_val(func, -1);
-
- // the begin offset
- tb_hize_t bof = tb_stream_offset(stream);
-
- // writ xplist header
- if (tb_stream_printf(stream, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>") < 0) return -1;
- if (!tb_oc_writer_newline(stream, deflate)) return -1;
- if (tb_stream_printf(stream, "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">") < 0) return -1;
- if (!tb_oc_writer_newline(stream, deflate)) return -1;
- if (tb_stream_printf(stream, "<plist version=\"1.0\">") < 0) return -1;
- if (!tb_oc_writer_newline(stream, deflate)) return -1;
-
- // writ
- if (!func(&writer, object, 0)) return -1;
-
- // writ xplist end
- if (tb_stream_printf(stream, "</plist>") < 0) return -1;
- if (!tb_oc_writer_newline(stream, deflate)) return -1;
-
- // sync
- if (!tb_stream_sync(stream, tb_true)) return -1;
-
- // the end offset
- tb_hize_t eof = tb_stream_offset(stream);
-
- // ok?
- return eof >= bof? (tb_long_t)(eof - bof) : -1;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-tb_oc_writer_t* tb_oc_xplist_writer()
-{
- // the writer
- static tb_oc_writer_t s_writer = {0};
-
- // init writer
- s_writer.writ = tb_oc_xplist_writer_done;
-
- // init hooker
- s_writer.hooker = tb_hash_map_init(TB_HASH_MAP_BUCKET_SIZE_MICRO, tb_element_uint32(), tb_element_ptr(tb_null, tb_null));
- tb_assert_and_check_return_val(s_writer.hooker, tb_null);
-
- // hook writer
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_DATE, tb_oc_xplist_writer_func_date);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_DATA, tb_oc_xplist_writer_func_data);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_ARRAY, tb_oc_xplist_writer_func_array);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_STRING, tb_oc_xplist_writer_func_string);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_NUMBER, tb_oc_xplist_writer_func_number);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_BOOLEAN, tb_oc_xplist_writer_func_boolean);
- tb_hash_map_insert(s_writer.hooker, (tb_pointer_t)TB_OBJECT_TYPE_DICTIONARY, tb_oc_xplist_writer_func_dictionary);
-
- // ok
- return &s_writer;
-}
-tb_bool_t tb_oc_xplist_writer_hook(tb_size_t type, tb_oc_xplist_writer_func_t func)
-{
- // check
- tb_assert_and_check_return_val(func, tb_false);
-
- // the writer
- tb_oc_writer_t* writer = tb_oc_writer_get(TB_OBJECT_FORMAT_XPLIST);
- tb_assert_and_check_return_val(writer && writer->hooker, tb_false);
-
- // hook it
- tb_hash_map_insert(writer->hooker, (tb_pointer_t)type, func);
-
- // ok
- return tb_true;
-}
-tb_oc_xplist_writer_func_t tb_oc_xplist_writer_func(tb_size_t type)
-{
- // the writer
- tb_oc_writer_t* writer = tb_oc_writer_get(TB_OBJECT_FORMAT_XPLIST);
- tb_assert_and_check_return_val(writer && writer->hooker, tb_null);
-
- // the func
- return (tb_oc_xplist_writer_func_t)tb_hash_map_get(writer->hooker, (tb_pointer_t)type);
-}
-
diff --git a/core/src/tbox/src/tbox/object/impl/writer/xplist.h b/core/src/tbox/src/tbox/object/impl/writer/xplist.h
deleted file mode 100644
index decf74ec3..000000000
--- a/core/src/tbox/src/tbox/object/impl/writer/xplist.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file xplist.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_IMPL_WRITER_XPLIST_H
-#define TB_OBJECT_IMPL_WRITER_XPLIST_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the object xplist writer type
-typedef struct __tb_oc_xplist_writer_t
-{
- /// the stream
- tb_stream_ref_t stream;
-
- /// is deflate?
- tb_bool_t deflate;
-
-}tb_oc_xplist_writer_t;
-
-/// the xplist writer func type
-typedef tb_bool_t (*tb_oc_xplist_writer_func_t)(tb_oc_xplist_writer_t* writer, tb_object_ref_t object, tb_size_t level);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! the xplist object writer
- *
- * @return the xplist object writer
- */
-tb_oc_writer_t* tb_oc_xplist_writer(tb_noarg_t);
-
-/*! hook the xplist writer
- *
- * @param type the object type
- * @param func the writer func
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_xplist_writer_hook(tb_size_t type, tb_oc_xplist_writer_func_t func);
-
-/*! the xplist writer func
- *
- * @param type the object type
- *
- * @return the object writer func
- */
-tb_oc_xplist_writer_func_t tb_oc_xplist_writer_func(tb_size_t type);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/null.c b/core/src/tbox/src/tbox/object/null.c
deleted file mode 100644
index 7a3c1fa31..000000000
--- a/core/src/tbox/src/tbox/object/null.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file null.c
- * @ingroup object
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "oc_null"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "object.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static tb_object_ref_t tb_oc_null_copy(tb_object_ref_t object)
-{
- return object;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * globals
- */
-
-// null
-static tb_object_t const g_null =
-{
- TB_OBJECT_FLAG_READONLY | TB_OBJECT_FLAG_SINGLETON
-, TB_OBJECT_TYPE_NULL
-, 1
-, tb_null
-, tb_oc_null_copy
-, tb_null
-, tb_null
-
-};
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-tb_object_ref_t tb_oc_null_init()
-{
- return (tb_object_ref_t)&g_null;
-}
-
diff --git a/core/src/tbox/src/tbox/object/null.h b/core/src/tbox/src/tbox/object/null.h
deleted file mode 100644
index c9c066f3b..000000000
--- a/core/src/tbox/src/tbox/object/null.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file null.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_NULL_H
-#define TB_OBJECT_NULL_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init null
- *
- * @return the null object
- */
-tb_object_ref_t tb_oc_null_init(tb_noarg_t);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/number.c b/core/src/tbox/src/tbox/object/number.c
deleted file mode 100644
index 5dbcd4e90..000000000
--- a/core/src/tbox/src/tbox/object/number.c
+++ /dev/null
@@ -1,683 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file number.c
- * @ingroup object
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "oc_number"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "object.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the number type
-typedef struct __tb_oc_number_t
-{
- // the object base
- tb_object_t base;
-
- // the number type
- tb_size_t type;
-
- // the number value
- union
- {
- // the uint8
- tb_uint8_t u8;
-
- // the sint8
- tb_sint8_t s8;
-
- // the uint16
- tb_uint16_t u16;
-
- // the sint16
- tb_sint16_t s16;
-
- // the uint32
- tb_uint32_t u32;
-
- // the sint32
- tb_sint32_t s32;
-
- // the uint64
- tb_uint64_t u64;
-
- // the sint64
- tb_sint64_t s64;
-
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- // the float
- tb_float_t f;
-
- // the double
- tb_double_t d;
-#endif
-
- }v;
-
-}tb_oc_number_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static __tb_inline__ tb_oc_number_t* tb_oc_number_cast(tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return_val(object && object->type == TB_OBJECT_TYPE_NUMBER, tb_null);
-
- // cast
- return (tb_oc_number_t*)object;
-}
-static tb_object_ref_t tb_oc_number_copy(tb_object_ref_t object)
-{
- // check
- tb_oc_number_t* number = (tb_oc_number_t*)object;
- tb_assert_and_check_return_val(number, tb_null);
-
- // copy
- switch (number->type)
- {
- case TB_OC_NUMBER_TYPE_UINT64:
- return tb_oc_number_init_from_uint64(number->v.u64);
- case TB_OC_NUMBER_TYPE_SINT64:
- return tb_oc_number_init_from_sint64(number->v.s64);
- case TB_OC_NUMBER_TYPE_UINT32:
- return tb_oc_number_init_from_uint32(number->v.u32);
- case TB_OC_NUMBER_TYPE_SINT32:
- return tb_oc_number_init_from_sint32(number->v.s32);
- case TB_OC_NUMBER_TYPE_UINT16:
- return tb_oc_number_init_from_uint16(number->v.u16);
- case TB_OC_NUMBER_TYPE_SINT16:
- return tb_oc_number_init_from_sint16(number->v.s16);
- case TB_OC_NUMBER_TYPE_UINT8:
- return tb_oc_number_init_from_uint8(number->v.u8);
- case TB_OC_NUMBER_TYPE_SINT8:
- return tb_oc_number_init_from_sint8(number->v.s8);
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- case TB_OC_NUMBER_TYPE_FLOAT:
- return tb_oc_number_init_from_float(number->v.f);
- case TB_OC_NUMBER_TYPE_DOUBLE:
- return tb_oc_number_init_from_double(number->v.d);
-#endif
- default:
- break;
- }
-
- return tb_null;
-}
-static tb_void_t tb_oc_number_exit(tb_object_ref_t object)
-{
- if (object) tb_free(object);
-}
-static tb_void_t tb_oc_number_clear(tb_object_ref_t object)
-{
- // check
- tb_oc_number_t* number = (tb_oc_number_t*)object;
- tb_assert_and_check_return(number);
-
- // clear
- switch (number->type)
- {
- case TB_OC_NUMBER_TYPE_UINT64:
- number->v.u64 = 0;
- break;
- case TB_OC_NUMBER_TYPE_SINT64:
- number->v.s64 = 0;
- break;
- case TB_OC_NUMBER_TYPE_UINT32:
- number->v.u32 = 0;
- break;
- case TB_OC_NUMBER_TYPE_SINT32:
- number->v.s32 = 0;
- break;
- case TB_OC_NUMBER_TYPE_UINT16:
- number->v.u16 = 0;
- break;
- case TB_OC_NUMBER_TYPE_SINT16:
- number->v.s16 = 0;
- break;
- case TB_OC_NUMBER_TYPE_UINT8:
- number->v.u8 = 0;
- break;
- case TB_OC_NUMBER_TYPE_SINT8:
- number->v.s8 = 0;
- break;
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- case TB_OC_NUMBER_TYPE_FLOAT:
- number->v.f = 0.;
- break;
- case TB_OC_NUMBER_TYPE_DOUBLE:
- number->v.d = 0.;
- break;
-#endif
- default:
- break;
- }
-}
-static tb_oc_number_t* tb_oc_number_init_base()
-{
- // done
- tb_bool_t ok = tb_false;
- tb_oc_number_t* number = tb_null;
- do
- {
- // make number
- number = tb_malloc0_type(tb_oc_number_t);
- tb_assert_and_check_break(number);
-
- // init number
- if (!tb_object_init((tb_object_ref_t)number, TB_OBJECT_FLAG_NONE, TB_OBJECT_TYPE_NUMBER)) break;
-
- // init base
- number->base.copy = tb_oc_number_copy;
- number->base.exit = tb_oc_number_exit;
- number->base.clear = tb_oc_number_clear;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (number) tb_object_exit((tb_object_ref_t)number);
- number = tb_null;
- }
-
- // ok?
- return number;
-}
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-tb_object_ref_t tb_oc_number_init_from_uint8(tb_uint8_t value)
-{
- // make
- tb_oc_number_t* number = tb_oc_number_init_base();
- tb_assert_and_check_return_val(number, tb_null);
-
- // init value
- number->type = TB_OC_NUMBER_TYPE_UINT8;
- number->v.u8 = value;
-
- // ok
- return (tb_object_ref_t)number;
-}
-
-tb_object_ref_t tb_oc_number_init_from_sint8(tb_sint8_t value)
-{
- // make
- tb_oc_number_t* number = tb_oc_number_init_base();
- tb_assert_and_check_return_val(number, tb_null);
-
- // init value
- number->type = TB_OC_NUMBER_TYPE_SINT8;
- number->v.s8 = value;
-
- // ok
- return (tb_object_ref_t)number;
-}
-
-tb_object_ref_t tb_oc_number_init_from_uint16(tb_uint16_t value)
-{
- // make
- tb_oc_number_t* number = tb_oc_number_init_base();
- tb_assert_and_check_return_val(number, tb_null);
-
- // init value
- number->type = TB_OC_NUMBER_TYPE_UINT16;
- number->v.u16 = value;
-
- // ok
- return (tb_object_ref_t)number;
-}
-
-tb_object_ref_t tb_oc_number_init_from_sint16(tb_sint16_t value)
-{
- // make
- tb_oc_number_t* number = tb_oc_number_init_base();
- tb_assert_and_check_return_val(number, tb_null);
-
- // init value
- number->type = TB_OC_NUMBER_TYPE_SINT16;
- number->v.s16 = value;
-
- // ok
- return (tb_object_ref_t)number;
-}
-
-tb_object_ref_t tb_oc_number_init_from_uint32(tb_uint32_t value)
-{
- // make
- tb_oc_number_t* number = tb_oc_number_init_base();
- tb_assert_and_check_return_val(number, tb_null);
-
- // init value
- number->type = TB_OC_NUMBER_TYPE_UINT32;
- number->v.u32 = value;
-
- // ok
- return (tb_object_ref_t)number;
-}
-
-tb_object_ref_t tb_oc_number_init_from_sint32(tb_sint32_t value)
-{
- // make
- tb_oc_number_t* number = tb_oc_number_init_base();
- tb_assert_and_check_return_val(number, tb_null);
-
- // init value
- number->type = TB_OC_NUMBER_TYPE_SINT32;
- number->v.s32 = value;
-
- // ok
- return (tb_object_ref_t)number;
-}
-
-tb_object_ref_t tb_oc_number_init_from_uint64(tb_uint64_t value)
-{
- // make
- tb_oc_number_t* number = tb_oc_number_init_base();
- tb_assert_and_check_return_val(number, tb_null);
-
- // init value
- number->type = TB_OC_NUMBER_TYPE_UINT64;
- number->v.u64 = value;
-
- // ok
- return (tb_object_ref_t)number;
-}
-
-tb_object_ref_t tb_oc_number_init_from_sint64(tb_sint64_t value)
-{
- // make
- tb_oc_number_t* number = tb_oc_number_init_base();
- tb_assert_and_check_return_val(number, tb_null);
-
- // init value
- number->type = TB_OC_NUMBER_TYPE_SINT64;
- number->v.s64 = value;
-
- // ok
- return (tb_object_ref_t)number;
-}
-
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
-tb_object_ref_t tb_oc_number_init_from_float(tb_float_t value)
-{
- // make
- tb_oc_number_t* number = tb_oc_number_init_base();
- tb_assert_and_check_return_val(number, tb_null);
-
- // init value
- number->type = TB_OC_NUMBER_TYPE_FLOAT;
- number->v.f = value;
-
- // ok
- return (tb_object_ref_t)number;
-}
-
-tb_object_ref_t tb_oc_number_init_from_double(tb_double_t value)
-{
- // make
- tb_oc_number_t* number = tb_oc_number_init_base();
- tb_assert_and_check_return_val(number, tb_null);
-
- // init value
- number->type = TB_OC_NUMBER_TYPE_DOUBLE;
- number->v.d = value;
-
- // ok
- return (tb_object_ref_t)number;
-}
-#endif
-
-tb_size_t tb_oc_number_type(tb_object_ref_t object)
-{
- // check
- tb_oc_number_t* number = tb_oc_number_cast(object);
- tb_assert_and_check_return_val(number, TB_OC_NUMBER_TYPE_NONE);
-
- // type
- return number->type;
-}
-
-tb_uint8_t tb_oc_number_uint8(tb_object_ref_t object)
-{
- return (tb_uint8_t)tb_oc_number_uint64(object);
-}
-tb_sint8_t tb_oc_number_sint8(tb_object_ref_t object)
-{
- return (tb_sint8_t)tb_oc_number_sint64(object);
-}
-tb_uint16_t tb_oc_number_uint16(tb_object_ref_t object)
-{
- return (tb_uint16_t)tb_oc_number_uint64(object);
-}
-tb_sint16_t tb_oc_number_sint16(tb_object_ref_t object)
-{
- return (tb_sint16_t)tb_oc_number_sint64(object);
-}
-tb_uint32_t tb_oc_number_uint32(tb_object_ref_t object)
-{
- return (tb_uint32_t)tb_oc_number_uint64(object);
-}
-tb_sint32_t tb_oc_number_sint32(tb_object_ref_t object)
-{
- return (tb_sint32_t)tb_oc_number_sint64(object);
-}
-tb_uint64_t tb_oc_number_uint64(tb_object_ref_t object)
-{
- // check
- tb_oc_number_t* number = tb_oc_number_cast(object);
- tb_assert_and_check_return_val(number, 0);
-
- // uint64
- switch (number->type)
- {
- case TB_OC_NUMBER_TYPE_UINT64:
- return number->v.u64;
- case TB_OC_NUMBER_TYPE_SINT64:
- return number->v.s64;
- case TB_OC_NUMBER_TYPE_UINT32:
- return number->v.u32;
- case TB_OC_NUMBER_TYPE_SINT32:
- return number->v.s32;
- case TB_OC_NUMBER_TYPE_UINT16:
- return number->v.u16;
- case TB_OC_NUMBER_TYPE_SINT16:
- return number->v.s16;
- case TB_OC_NUMBER_TYPE_UINT8:
- return number->v.u8;
- case TB_OC_NUMBER_TYPE_SINT8:
- return number->v.s8;
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- case TB_OC_NUMBER_TYPE_FLOAT:
- return (tb_uint64_t)number->v.f;
- case TB_OC_NUMBER_TYPE_DOUBLE:
- return (tb_uint64_t)number->v.d;
-#endif
- default:
- break;
- }
-
- tb_assert(0);
- return 0;
-}
-
-tb_sint64_t tb_oc_number_sint64(tb_object_ref_t object)
-{
- // check
- tb_oc_number_t* number = tb_oc_number_cast(object);
- tb_assert_and_check_return_val(number, 0);
-
- // sint64
- switch (number->type)
- {
- case TB_OC_NUMBER_TYPE_UINT64:
- return number->v.u64;
- case TB_OC_NUMBER_TYPE_SINT64:
- return number->v.s64;
- case TB_OC_NUMBER_TYPE_UINT32:
- return number->v.u32;
- case TB_OC_NUMBER_TYPE_SINT32:
- return number->v.s32;
- case TB_OC_NUMBER_TYPE_UINT16:
- return number->v.u16;
- case TB_OC_NUMBER_TYPE_SINT16:
- return number->v.s16;
- case TB_OC_NUMBER_TYPE_UINT8:
- return number->v.u8;
- case TB_OC_NUMBER_TYPE_SINT8:
- return number->v.s8;
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
- case TB_OC_NUMBER_TYPE_FLOAT:
- return (tb_sint64_t)number->v.f;
- case TB_OC_NUMBER_TYPE_DOUBLE:
- return (tb_sint64_t)number->v.d;
-#endif
- default:
- break;
- }
-
- tb_assert(0);
- return 0;
-}
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
-tb_float_t tb_oc_number_float(tb_object_ref_t object)
-{
- // check
- tb_oc_number_t* number = tb_oc_number_cast(object);
- tb_assert_and_check_return_val(number, 0);
-
- // float
- switch (number->type)
- {
- case TB_OC_NUMBER_TYPE_FLOAT:
- return number->v.f;
- case TB_OC_NUMBER_TYPE_DOUBLE:
- return (tb_float_t)number->v.d;
- case TB_OC_NUMBER_TYPE_UINT8:
- return (tb_float_t)number->v.u8;
- case TB_OC_NUMBER_TYPE_SINT8:
- return (tb_float_t)number->v.s8;
- case TB_OC_NUMBER_TYPE_UINT16:
- return (tb_float_t)number->v.u16;
- case TB_OC_NUMBER_TYPE_SINT16:
- return (tb_float_t)number->v.s16;
- case TB_OC_NUMBER_TYPE_UINT32:
- return (tb_float_t)number->v.u32;
- case TB_OC_NUMBER_TYPE_SINT32:
- return (tb_float_t)number->v.s32;
- case TB_OC_NUMBER_TYPE_UINT64:
- return (tb_float_t)number->v.u64;
- case TB_OC_NUMBER_TYPE_SINT64:
- return (tb_float_t)number->v.s64;
- default:
- break;
- }
-
- tb_assert(0);
- return 0;
-}
-tb_double_t tb_oc_number_double(tb_object_ref_t object)
-{
- // check
- tb_oc_number_t* number = tb_oc_number_cast(object);
- tb_assert_and_check_return_val(number, 0);
-
- // double
- switch (number->type)
- {
- case TB_OC_NUMBER_TYPE_DOUBLE:
- return number->v.d;
- case TB_OC_NUMBER_TYPE_FLOAT:
- return (tb_double_t)number->v.f;
- case TB_OC_NUMBER_TYPE_UINT8:
- return (tb_double_t)number->v.u8;
- case TB_OC_NUMBER_TYPE_SINT8:
- return (tb_double_t)number->v.s8;
- case TB_OC_NUMBER_TYPE_UINT16:
- return (tb_double_t)number->v.u16;
- case TB_OC_NUMBER_TYPE_SINT16:
- return (tb_double_t)number->v.s16;
- case TB_OC_NUMBER_TYPE_UINT32:
- return (tb_double_t)number->v.u32;
- case TB_OC_NUMBER_TYPE_SINT32:
- return (tb_double_t)number->v.s32;
- case TB_OC_NUMBER_TYPE_UINT64:
- return (tb_double_t)number->v.u64;
- case TB_OC_NUMBER_TYPE_SINT64:
- return (tb_double_t)number->v.s64;
- default:
- break;
- }
-
- tb_assert(0);
- return 0;
-}
-#endif
-tb_bool_t tb_oc_number_uint8_set(tb_object_ref_t object, tb_uint8_t value)
-{
- // check
- tb_oc_number_t* number = tb_oc_number_cast(object);
- tb_assert_and_check_return_val(number, tb_false);
-
- // init value
- number->type = TB_OC_NUMBER_TYPE_UINT8;
- number->v.u8 = value;
-
- // ok
- return tb_true;
-}
-tb_bool_t tb_oc_number_sint8_set(tb_object_ref_t object, tb_sint8_t value)
-{
- // check
- tb_oc_number_t* number = tb_oc_number_cast(object);
- tb_assert_and_check_return_val(number, tb_false);
-
- // init value
- number->type = TB_OC_NUMBER_TYPE_SINT8;
- number->v.s8 = value;
-
- // ok
- return tb_true;
-}
-tb_bool_t tb_oc_number_uint16_set(tb_object_ref_t object, tb_uint16_t value)
-{
- // check
- tb_oc_number_t* number = tb_oc_number_cast(object);
- tb_assert_and_check_return_val(number, tb_false);
-
- // init value
- number->type = TB_OC_NUMBER_TYPE_UINT16;
- number->v.u16 = value;
-
- // ok
- return tb_true;
-}
-tb_bool_t tb_oc_number_sint16_set(tb_object_ref_t object, tb_sint16_t value)
-{
- // check
- tb_oc_number_t* number = tb_oc_number_cast(object);
- tb_assert_and_check_return_val(number, tb_false);
-
- // init value
- number->type = TB_OC_NUMBER_TYPE_SINT16;
- number->v.s16 = value;
-
- // ok
- return tb_true;
-}
-tb_bool_t tb_oc_number_uint32_set(tb_object_ref_t object, tb_uint32_t value)
-{
- // check
- tb_oc_number_t* number = tb_oc_number_cast(object);
- tb_assert_and_check_return_val(number, tb_false);
-
- // init value
- number->type = TB_OC_NUMBER_TYPE_UINT32;
- number->v.u32 = value;
-
- // ok
- return tb_true;
-}
-tb_bool_t tb_oc_number_sint32_set(tb_object_ref_t object, tb_sint32_t value)
-{
- // check
- tb_oc_number_t* number = tb_oc_number_cast(object);
- tb_assert_and_check_return_val(number, tb_false);
-
- // init value
- number->type = TB_OC_NUMBER_TYPE_SINT32;
- number->v.s32 = value;
-
- // ok
- return tb_true;
-}
-tb_bool_t tb_oc_number_uint64_set(tb_object_ref_t object, tb_uint64_t value)
-{
- // check
- tb_oc_number_t* number = tb_oc_number_cast(object);
- tb_assert_and_check_return_val(number, tb_false);
-
- // init value
- number->type = TB_OC_NUMBER_TYPE_UINT64;
- number->v.u64 = value;
-
- // ok
- return tb_true;
-}
-tb_bool_t tb_oc_number_sint64_set(tb_object_ref_t object, tb_sint64_t value)
-{
- // check
- tb_oc_number_t* number = tb_oc_number_cast(object);
- tb_assert_and_check_return_val(number, tb_false);
-
- // init value
- number->type = TB_OC_NUMBER_TYPE_SINT64;
- number->v.s64 = value;
-
- // ok
- return tb_true;
-}
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
-tb_bool_t tb_oc_number_float_set(tb_object_ref_t object, tb_float_t value)
-{
- // check
- tb_oc_number_t* number = tb_oc_number_cast(object);
- tb_assert_and_check_return_val(number, tb_false);
-
- // init value
- number->type = TB_OC_NUMBER_TYPE_FLOAT;
- number->v.f = value;
-
- // ok
- return tb_true;
-}
-tb_bool_t tb_oc_number_double_set(tb_object_ref_t object, tb_double_t value)
-{
- // check
- tb_oc_number_t* number = tb_oc_number_cast(object);
- tb_assert_and_check_return_val(number, tb_false);
-
- // init value
- number->type = TB_OC_NUMBER_TYPE_DOUBLE;
- number->v.d = value;
-
- // ok
- return tb_true;
-}
-#endif
diff --git a/core/src/tbox/src/tbox/object/number.h b/core/src/tbox/src/tbox/object/number.h
deleted file mode 100644
index d518906cf..000000000
--- a/core/src/tbox/src/tbox/object/number.h
+++ /dev/null
@@ -1,334 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file number.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_NUMBER_H
-#define TB_OBJECT_NUMBER_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the number type enum
-typedef enum __tb_oc_number_type_e
-{
- TB_OC_NUMBER_TYPE_NONE = 0
-, TB_OC_NUMBER_TYPE_UINT8 = 1
-, TB_OC_NUMBER_TYPE_SINT8 = 2
-, TB_OC_NUMBER_TYPE_UINT16 = 3
-, TB_OC_NUMBER_TYPE_SINT16 = 4
-, TB_OC_NUMBER_TYPE_UINT32 = 5
-, TB_OC_NUMBER_TYPE_SINT32 = 6
-, TB_OC_NUMBER_TYPE_UINT64 = 7
-, TB_OC_NUMBER_TYPE_SINT64 = 8
-, TB_OC_NUMBER_TYPE_FLOAT = 9
-, TB_OC_NUMBER_TYPE_DOUBLE = 10
-
-}tb_oc_number_type_e;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init number from uint8
- *
- * @param value the value
- *
- * @return the number object
- */
-tb_object_ref_t tb_oc_number_init_from_uint8(tb_uint8_t value);
-
-/*! init number from sint8
- *
- * @param value the value
- *
- * @return the number object
- */
-tb_object_ref_t tb_oc_number_init_from_sint8(tb_sint8_t value);
-
-/*! init number from uint16
- *
- * @param value the value
- *
- * @return the number object
- */
-tb_object_ref_t tb_oc_number_init_from_uint16(tb_uint16_t value);
-
-/*! init number from sint16
- *
- * @param value the value
- *
- * @return the number object
- */
-tb_object_ref_t tb_oc_number_init_from_sint16(tb_sint16_t value);
-
-/*! init number from uint32
- *
- * @param value the value
- *
- * @return the number object
- */
-tb_object_ref_t tb_oc_number_init_from_uint32(tb_uint32_t value);
-
-/*! init number from sint32
- *
- * @param value the value
- *
- * @return the number object
- */
-tb_object_ref_t tb_oc_number_init_from_sint32(tb_sint32_t value);
-
-/*! init number from uint64
- *
- * @param value the value
- *
- * @return the number object
- */
-tb_object_ref_t tb_oc_number_init_from_uint64(tb_uint64_t value);
-
-/*! init number from sint64
- *
- * @param value the value
- *
- * @return the number object
- */
-tb_object_ref_t tb_oc_number_init_from_sint64(tb_sint64_t value);
-
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
-/*! init number from float
- *
- * @param value the value
- *
- * @return the number object
- */
-tb_object_ref_t tb_oc_number_init_from_float(tb_float_t value);
-
-/*! init number from double
- *
- * @param value the value
- *
- * @return the number object
- */
-tb_object_ref_t tb_oc_number_init_from_double(tb_double_t value);
-#endif
-
-/*! the number type
- *
- * @param object the object pointer
- *
- * @return the number type
- */
-tb_size_t tb_oc_number_type(tb_object_ref_t number);
-
-/*! the uint8 value of the number
- *
- * @param object the object pointer
- *
- * @return the number value
- */
-tb_uint8_t tb_oc_number_uint8(tb_object_ref_t number);
-
-/*! the sint8 value of the number
- *
- * @param object the object pointer
- *
- * @return the number value
- */
-tb_sint8_t tb_oc_number_sint8(tb_object_ref_t number);
-
-/*! the uint16 value of the number
- *
- * @param object the object pointer
- *
- * @return the number value
- */
-tb_uint16_t tb_oc_number_uint16(tb_object_ref_t number);
-
-/*! the sint16 value of the number
- *
- * @param object the object pointer
- *
- * @return the number value
- */
-tb_sint16_t tb_oc_number_sint16(tb_object_ref_t number);
-
-/*! the uint32 value of the number
- *
- * @param object the object pointer
- *
- * @return the number value
- */
-tb_uint32_t tb_oc_number_uint32(tb_object_ref_t number);
-
-/*! the sint32 value of the number
- *
- * @param object the object pointer
- *
- * @return the number value
- */
-tb_sint32_t tb_oc_number_sint32(tb_object_ref_t number);
-
-/*! the uint64 value of the number
- *
- * @param object the object pointer
- *
- * @return the number value
- */
-tb_uint64_t tb_oc_number_uint64(tb_object_ref_t number);
-
-/*! the sint64 value of the number
- *
- * @param object the object pointer
- *
- * @return the number value
- */
-tb_sint64_t tb_oc_number_sint64(tb_object_ref_t number);
-
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
-/*! the float value of the number
- *
- * @param object the object pointer
- *
- * @return the number value
- */
-tb_float_t tb_oc_number_float(tb_object_ref_t number);
-
-/*! the double value of the number
- *
- * @param object the object pointer
- *
- * @return the number value
- */
-tb_double_t tb_oc_number_double(tb_object_ref_t number);
-#endif
-
-/*! set the uint8 value
- *
- * @param object the object pointer
- * @param value the number value
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_number_uint8_set(tb_object_ref_t number, tb_uint8_t value);
-
-/*! set the sint8 value
- *
- * @param object the object pointer
- * @param value the number value
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_number_sint8_set(tb_object_ref_t number, tb_sint8_t value);
-
-/*! set the uint16 value
- *
- * @param object the object pointer
- * @param value the number value
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_number_uint16_set(tb_object_ref_t number, tb_uint16_t value);
-
-/*! set the sint16 value
- *
- * @param object the object pointer
- * @param value the number value
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_number_sint16_set(tb_object_ref_t number, tb_sint16_t value);
-
-/*! set the uint32 value
- *
- * @param object the object pointer
- * @param value the number value
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_number_uint32_set(tb_object_ref_t number, tb_uint32_t value);
-
-/*! set the sint32 value
- *
- * @param object the object pointer
- * @param value the number value
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_number_sint32_set(tb_object_ref_t number, tb_sint32_t value);
-
-/*! set the uint64 value
- *
- * @param object the object pointer
- * @param value the number value
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_number_uint64_set(tb_object_ref_t number, tb_uint64_t value);
-
-/*! set the sint64 value
- *
- * @param object the object pointer
- * @param value the number value
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_number_sint64_set(tb_object_ref_t number, tb_sint64_t value);
-
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
-/*! set the float value
- *
- * @param object the object pointer
- * @param value the number value
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_number_float_set(tb_object_ref_t number, tb_float_t value);
-
-/*! set the double value
- *
- * @param object the object pointer
- * @param value the number value
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_oc_number_double_set(tb_object_ref_t number, tb_double_t value);
-#endif
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/object.c b/core/src/tbox/src/tbox/object/object.c
deleted file mode 100644
index b92c0c4b2..000000000
--- a/core/src/tbox/src/tbox/object/object.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file object.c
- * @ingroup object
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "object"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "object.h"
-#include "impl/impl.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_bool_t tb_object_init(tb_object_ref_t object, tb_size_t flag, tb_size_t type)
-{
- // check
- tb_assert_and_check_return_val(object, tb_false);
-
- // init
- tb_memset(object, 0, sizeof(tb_object_t));
- object->flag = (tb_uint8_t)flag;
- object->type = (tb_uint16_t)type;
- object->refn = 1;
-
- // ok
- return tb_true;
-}
-tb_void_t tb_object_exit(tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return(object);
-
- // readonly?
- tb_check_return(!(object->flag & TB_OBJECT_FLAG_READONLY));
-
- // check refn
- tb_assert_and_check_return(object->refn);
-
- // refn--
- object->refn--;
-
- // exit it?
- if (!object->refn && object->exit) object->exit(object);
-}
-tb_void_t tb_object_clear(tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return(object);
-
- // readonly?
- tb_check_return(!(object->flag & TB_OBJECT_FLAG_READONLY));
-
- // clear
- if (object->clear) object->clear(object);
-}
-tb_void_t tb_object_setp(tb_object_ref_t object, tb_cpointer_t priv)
-{
- // check
- tb_assert_and_check_return(object);
-
- // set it
- object->priv = priv;
-}
-tb_cpointer_t tb_object_getp(tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return_val(object, tb_null);
-
- // get it
- return object->priv;
-}
-tb_object_ref_t tb_object_copy(tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return_val(object && object->copy, tb_null);
-
- // copy
- return object->copy(object);
-}
-tb_size_t tb_object_type(tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return_val(object, TB_OBJECT_TYPE_NONE);
-
- // the object type
- return object->type;
-}
-tb_object_ref_t tb_object_data(tb_object_ref_t object, tb_size_t format)
-{
- // check
- tb_assert_and_check_return_val(object, tb_null);
-
- // done
- tb_object_ref_t odata = tb_null;
- tb_size_t maxn = TB_STREAM_BLOCK_MAXN;
- tb_byte_t* data = tb_null;
- do
- {
- // make data
- data = data? (tb_byte_t*)tb_ralloc(data, maxn) : tb_malloc_bytes(maxn);
- tb_assert_and_check_break(data);
-
- // writ object to data
- tb_long_t size = tb_object_writ_to_data(object, data, maxn, format);
-
- // ok? make the data object
- if (size >= 0) odata = tb_oc_data_init_from_data(data, size);
- // failed? grow it
- else maxn <<= 1;
-
- } while (!odata);
-
- // exit data
- if (data) tb_free(data);
- data = tb_null;
-
- // ok?
- return odata;
-}
-tb_object_ref_t tb_object_seek(tb_object_ref_t object, tb_char_t const* path, tb_bool_t bmacro)
-{
- // check
- tb_assert_and_check_return_val(object, tb_null);
-
- // null?
- tb_check_return_val(path, object);
-
- // done
- tb_object_ref_t root = object;
- tb_char_t const* p = path;
- tb_char_t const* e = path + tb_strlen(path);
- while (p < e && object)
- {
- // done seek
- switch (*p)
- {
- case '.':
- {
- // check
- tb_assert_and_check_return_val(tb_object_type(object) == TB_OBJECT_TYPE_DICTIONARY, tb_null);
-
- // skip
- p++;
-
- // read the key name
- tb_char_t key[4096] = {0};
- tb_char_t* kb = key;
- tb_char_t* ke = key + 4095;
- for (; p < e && kb < ke && *p && (*p != '.' && *p != '[' && *p != ']'); p++, kb++)
- {
- if (*p == '\\') p++;
- *kb = *p;
- }
-
- // trace
- tb_trace_d("key: %s", key);
-
- // the value
- object = tb_oc_dictionary_value(object, key);
- }
- break;
- case '[':
- {
- // check
- tb_assert_and_check_return_val(tb_object_type(object) == TB_OBJECT_TYPE_ARRAY, tb_null);
-
- // skip
- p++;
-
- // read the item index
- tb_char_t index[32] = {0};
- tb_char_t* ib = index;
- tb_char_t* ie = index + 31;
- for (; p < e && ib < ie && *p && tb_isdigit10(*p); p++, ib++) *ib = *p;
-
- // trace
- tb_trace_d("index: %s", index);
-
- // check
- tb_size_t i = tb_atoi(index);
- tb_assert_and_check_return_val(i < tb_oc_array_size(object), tb_null);
-
- // the value
- object = tb_oc_array_item(object, i);
- }
- break;
- case ']':
- default:
- p++;
- break;
- }
-
- // is macro? done it if be enabled
- if ( object
- && bmacro
- && tb_object_type(object) == TB_OBJECT_TYPE_STRING
- && tb_oc_string_size(object)
- && tb_oc_string_cstr(object)[0] == '$')
- {
- // the next path
- path = tb_oc_string_cstr(object) + 1;
-
- // continue to seek it
- object = tb_object_seek(root, path, bmacro);
- }
- }
-
- // ok?
- return object;
-}
-tb_object_ref_t tb_object_dump(tb_object_ref_t object, tb_size_t format)
-{
- // check
- tb_assert_and_check_return_val(object, tb_null);
-
- // data
- tb_object_ref_t odata = tb_object_data(object, format);
- if (odata)
- {
- // the data and size
- tb_byte_t const* data = (tb_byte_t const*)tb_oc_data_getp(odata);
- tb_size_t size = tb_oc_data_size(odata);
- if (data && size)
- {
- // done
- tb_char_t const* p = (tb_char_t const*)data;
- tb_char_t const* e = (tb_char_t const*)data + size;
- tb_char_t b[4096 + 1];
- if (p && p < e)
- {
- while (p < e && *p && tb_isspace(*p)) p++;
- while (p < e && *p)
- {
- tb_char_t* q = b;
- tb_char_t const* d = b + 4096;
- for (; p < e && q < d && *p; p++, q++) *q = *p;
- *q = '\0';
- tb_printf("%s", b);
- }
- tb_printf("\n");
- }
- }
-
- // exit data
- tb_object_exit(odata);
- }
-
- // the object
- return object;
-}
-tb_size_t tb_object_refn(tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return_val(object, 0);
-
- // get it
- return object->refn;
-}
-tb_void_t tb_object_retain(tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return(object);
-
- // readonly?
- tb_check_return(!(object->flag & TB_OBJECT_FLAG_READONLY));
-
- // refn++
- object->refn++;
-}
-tb_object_ref_t tb_object_read(tb_stream_ref_t stream)
-{
- // check
- tb_assert_and_check_return_val(stream, tb_null);
-
- // done reader
- return tb_oc_reader_done(stream);
-}
-tb_object_ref_t tb_object_read_from_url(tb_char_t const* url)
-{
- // check
- tb_assert_and_check_return_val(url, tb_null);
-
- // init
- tb_object_ref_t object = tb_null;
-
- // make stream
- tb_stream_ref_t stream = tb_stream_init_from_url(url);
- tb_assert_and_check_return_val(stream, tb_null);
-
- // read object
- if (tb_stream_open(stream)) object = tb_object_read(stream);
-
- // exit stream
- tb_stream_exit(stream);
-
- // ok?
- return object;
-}
-tb_object_ref_t tb_object_read_from_data(tb_byte_t const* data, tb_size_t size)
-{
- // check
- tb_assert_and_check_return_val(data && size, tb_null);
-
- // init
- tb_object_ref_t object = tb_null;
-
- // make stream
- tb_stream_ref_t stream = tb_stream_init_from_data(data, size);
- tb_assert_and_check_return_val(stream, tb_null);
-
- // read object
- if (tb_stream_open(stream)) object = tb_object_read(stream);
-
- // exit stream
- tb_stream_exit(stream);
-
- // ok?
- return object;
-}
-tb_long_t tb_object_writ(tb_object_ref_t object, tb_stream_ref_t stream, tb_size_t format)
-{
- // check
- tb_assert_and_check_return_val(object && stream, -1);
-
- // for xml
-#ifndef TB_CONFIG_MODULE_HAVE_XML
- tb_assertf(format != TB_OBJECT_FORMAT_XML || format != TB_OBJECT_FORMAT_XPLIST, "please enable xml module first!");
-#endif
-
- // writ it
- return tb_oc_writer_done(object, stream, format);
-}
-tb_long_t tb_object_writ_to_url(tb_object_ref_t object, tb_char_t const* url, tb_size_t format)
-{
- // check
- tb_assert_and_check_return_val(object && url, -1);
-
- // make stream
- tb_long_t writ = -1;
- tb_stream_ref_t stream = tb_stream_init_from_url(url);
- if (stream)
- {
- // ctrl stream
- if (tb_stream_type(stream) == TB_STREAM_TYPE_FILE)
- tb_stream_ctrl(stream, TB_STREAM_CTRL_FILE_SET_MODE, TB_FILE_MODE_RW | TB_FILE_MODE_CREAT | TB_FILE_MODE_TRUNC);
-
- // open and writ stream
- if (tb_stream_open(stream)) writ = tb_object_writ(object, stream, format);
-
- // exit stream
- tb_stream_exit(stream);
- }
-
- // ok?
- return writ;
-}
-tb_long_t tb_object_writ_to_data(tb_object_ref_t object, tb_byte_t* data, tb_size_t size, tb_size_t format)
-{
- // check
- tb_assert_and_check_return_val(object && data && size, -1);
-
- // make stream
- tb_long_t writ = -1;
- tb_stream_ref_t stream = tb_stream_init_from_data(data, size);
- if (stream)
- {
- // open and writ stream
- if (tb_stream_open(stream)) writ = tb_object_writ(object, stream, format);
-
- // exit stream
- tb_stream_exit(stream);
- }
-
- // ok?
- return writ;
-}
-
diff --git a/core/src/tbox/src/tbox/object/object.h b/core/src/tbox/src/tbox/object/object.h
deleted file mode 100644
index 0a3c9108f..000000000
--- a/core/src/tbox/src/tbox/object/object.h
+++ /dev/null
@@ -1,258 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file object.h
- * @defgroup object
- *
- */
-#ifndef TB_OBJECT_H
-#define TB_OBJECT_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-#include "null.h"
-#include "data.h"
-#include "date.h"
-#include "array.h"
-#include "string.h"
-#include "number.h"
-#include "boolean.h"
-#include "dictionary.h"
-#ifdef TB_CONFIG_API_HAVE_DEPRECATED
-# include "deprecated/deprecated.h"
-#endif
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init object
- *
- * @param object the object
- * @param flag the object flag
- * @param type the object type
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_object_init(tb_object_ref_t object, tb_size_t flag, tb_size_t type);
-
-/*! decrease the object reference count, will exit it if --refn == 0
- *
- * @param object the object
- *
- * @note the reference count must be one
- */
-tb_void_t tb_object_exit(tb_object_ref_t object);
-
-/*! clear object
- *
- * @param object the object
- */
-tb_void_t tb_object_clear(tb_object_ref_t object);
-
-/*! set the object private data
- *
- * @param object the object
- * @param priv the private data
- *
- */
-tb_void_t tb_object_setp(tb_object_ref_t object, tb_cpointer_t priv);
-
-/*! get the object private data
- *
- * @param object the object
- *
- * @return the private data
- */
-tb_cpointer_t tb_object_getp(tb_object_ref_t object);
-
-/*! read object
- *
- * @param stream the stream
- *
- * @return the object
- */
-tb_object_ref_t tb_object_read(tb_stream_ref_t stream);
-
-/*! read object from url
- *
- * @param url the url
- *
- * @return the object
- */
-tb_object_ref_t tb_object_read_from_url(tb_char_t const* url);
-
-/*! read object from data
- *
- * @param data the data
- * @param size the size
- *
- * @return the object
- */
-tb_object_ref_t tb_object_read_from_data(tb_byte_t const* data, tb_size_t size);
-
-/*! writ object
- *
- * @param object the object
- * @param stream the stream
- * @param format the object format
- *
- * @return the writed size, failed: -1
- */
-tb_long_t tb_object_writ(tb_object_ref_t object, tb_stream_ref_t stream, tb_size_t format);
-
-/*! writ object to url
- *
- * @param object the object
- * @param url the url
- * @param format the format
- *
- * @return the writed size, failed: -1
- */
-tb_long_t tb_object_writ_to_url(tb_object_ref_t object, tb_char_t const* url, tb_size_t format);
-
-/*! writ object to data
- *
- * @param object the object
- * @param data the data
- * @param size the size
- * @param format the format
- *
- * @return the writed size, failed: -1
- */
-tb_long_t tb_object_writ_to_data(tb_object_ref_t object, tb_byte_t* data, tb_size_t size, tb_size_t format);
-
-/*! copy object
- *
- * @param object the object
- *
- * @return the object copy
- */
-tb_object_ref_t tb_object_copy(tb_object_ref_t object);
-
-/*! the object type
- *
- * @param object the object
- *
- * @return the object type
- */
-tb_size_t tb_object_type(tb_object_ref_t object);
-
-/*! the object data
- *
- * @param object the object
- * @param format the format
- *
- * @return the data object
- */
-tb_object_ref_t tb_object_data(tb_object_ref_t object, tb_size_t format);
-
-/*! seek to the object for the gived path
- *
- * <pre>
- *
- file:
- {
- "string": "hello world!"
- , "com.xxx.xxx": "hello world"
- , "integer": 31415926
- , "array":
- [
- "hello world!"
- , 31415926
- , 3.1415926
- , false
- , true
- , { "string": "hello world!" }
- ]
- , "macro": "$.array[2]"
- , "macro2": "$.com\\\\.xxx\\\\.xxx"
- , "macro3": "$.macro"
- , "macro4": "$.array"
- }
-
- path:
- 1. ".string" : hello world!
- 2. ".array[1]" : 31415926
- 3. ".array[5].string" : hello world!
- 4. ".com\\.xxx\\.xxx" : hello world
- 5. ".macro" : 3.1415926
- 6. ".macro2" : hello world
- 7. ".macro3" : 3.1415926
- 8. ".macro4[0]" : "hello world!"
-
- *
- * </pre>
- *
- * @param object the object
- * @param path the object path
- * @param bmacro enable macro(like "$.path")?
- *
- * <code>
- * tb_object_ref_t object = tb_object_seek(root, ".array[5].string", tb_false);
- * if (object)
- * {
- * tb_trace_d("%s", tb_oc_string_cstr(object));
- * }
- * <endcode>
- *
- *
- * @return the object
- */
-tb_object_ref_t tb_object_seek(tb_object_ref_t object, tb_char_t const* path, tb_bool_t bmacro);
-
-/*! dump the object
- *
- * @param object the object
- * @param format the format, support: .xml, .xplist, .json
- *
- * @return the object
- */
-tb_object_ref_t tb_object_dump(tb_object_ref_t object, tb_size_t format);
-
-/*! the object reference count
- *
- * @param object the object
- *
- * @return the object reference count
- */
-tb_size_t tb_object_refn(tb_object_ref_t object);
-
-/*! retain object and increase the object reference count
- *
- * @param object the object
- */
-tb_void_t tb_object_retain(tb_object_ref_t object);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/object/prefix.h b/core/src/tbox/src/tbox/object/prefix.h
deleted file mode 100644
index 837adcea6..000000000
--- a/core/src/tbox/src/tbox/object/prefix.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file prefix.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_PREFIX_H
-#define TB_OBJECT_PREFIX_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "../prefix.h"
-#include "../xml/xml.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the object type enum
-typedef enum __tb_object_type_e
-{
- TB_OBJECT_TYPE_NONE = 0
-, TB_OBJECT_TYPE_DATA = 1
-, TB_OBJECT_TYPE_DATE = 2
-, TB_OBJECT_TYPE_ARRAY = 3
-, TB_OBJECT_TYPE_STRING = 4
-, TB_OBJECT_TYPE_NUMBER = 5
-, TB_OBJECT_TYPE_BOOLEAN = 6
-, TB_OBJECT_TYPE_DICTIONARY = 7
-, TB_OBJECT_TYPE_NULL = 8
-, TB_OBJECT_TYPE_USER = 9 //!< the user defined type, ...
-
-}tb_object_type_e;
-
-/// the object flag enum
-typedef enum __tb_object_flag_e
-{
- TB_OBJECT_FLAG_NONE = 0
-, TB_OBJECT_FLAG_READONLY = 1
-, TB_OBJECT_FLAG_SINGLETON = 2
-
-}tb_object_flag_e;
-
-/// the object format enum
-typedef enum __tb_object_format_e
-{
- TB_OBJECT_FORMAT_NONE = 0x0000 //!< none
-, TB_OBJECT_FORMAT_BIN = 0x0001 //!< the tbox binary format
-, TB_OBJECT_FORMAT_BPLIST = 0x0002 //!< the bplist format for apple
-, TB_OBJECT_FORMAT_XPLIST = 0x0003 //!< the xplist format for apple
-, TB_OBJECT_FORMAT_XML = 0x0004 //!< the xml format
-, TB_OBJECT_FORMAT_JSON = 0x0005 //!< the json format
-, TB_OBJECT_FORMAT_MAXN = 0x000f //!< the format maxn
-, TB_OBJECT_FORMAT_DEFLATE = 0x0100 //!< deflate?
-
-}tb_object_format_e;
-
-/// the object type
-typedef struct __tb_object_t
-{
- /// the object flag
- tb_uint8_t flag;
-
- /// the object type
- tb_uint16_t type;
-
- /// the object reference count
- tb_size_t refn;
-
- /// the object private data
- tb_cpointer_t priv;
-
- /// the copy func
- struct __tb_object_t* (*copy)(struct __tb_object_t* object);
-
- /// the clear func
- tb_void_t (*clear)(struct __tb_object_t* object);
-
- /// the exit func
- tb_void_t (*exit)(struct __tb_object_t* object);
-
-}tb_object_t, *tb_object_ref_t;
-
-#endif
diff --git a/core/src/tbox/src/tbox/object/string.c b/core/src/tbox/src/tbox/object/string.c
deleted file mode 100644
index f531bddc4..000000000
--- a/core/src/tbox/src/tbox/object/string.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file string.c
- * @ingroup object
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "oc_string"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "object.h"
-#include "../string/string.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-// the scache string size
-#define TB_OBJECT_STRING_CACHE_SIZE (64)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the string type
-typedef struct __tb_oc_string_t
-{
- // the object base
- tb_object_t base;
-
- // the string
- tb_string_t str;
-
-}tb_oc_string_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-static __tb_inline__ tb_oc_string_t* tb_oc_string_cast(tb_object_ref_t object)
-{
- // check
- tb_assert_and_check_return_val(object && object->type == TB_OBJECT_TYPE_STRING, tb_null);
-
- // cast
- return (tb_oc_string_t*)object;
-}
-static tb_object_ref_t tb_oc_string_copy(tb_object_ref_t object)
-{
- return tb_oc_string_init_from_cstr(tb_oc_string_cstr(object));
-}
-static tb_void_t tb_oc_string_exit(tb_object_ref_t object)
-{
- tb_oc_string_t* string = tb_oc_string_cast(object);
- if (string)
- {
- // exit the string
- tb_string_exit(&string->str);
-
- // exit the object
- tb_free(object);
- }
-}
-static tb_void_t tb_oc_string_clear(tb_object_ref_t object)
-{
- tb_oc_string_t* string = tb_oc_string_cast(object);
- if (string)
- {
- // clear the string
- tb_string_clear(&string->str);
- }
-}
-static tb_oc_string_t* tb_oc_string_init_base()
-{
- // done
- tb_bool_t ok = tb_false;
- tb_oc_string_t* string = tb_null;
- do
- {
- // make string
- string = tb_malloc0_type(tb_oc_string_t);
- tb_assert_and_check_break(string);
-
- // init string
- if (!tb_object_init((tb_object_ref_t)string, TB_OBJECT_FLAG_NONE, TB_OBJECT_TYPE_STRING)) break;
-
- // init base
- string->base.copy = tb_oc_string_copy;
- string->base.exit = tb_oc_string_exit;
- string->base.clear = tb_oc_string_clear;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (string) tb_object_exit((tb_object_ref_t)string);
- string = tb_null;
- }
-
- // ok?
- return string;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-tb_object_ref_t tb_oc_string_init_from_cstr(tb_char_t const* cstr)
-{
- // done
- tb_bool_t ok = tb_false;
- tb_oc_string_t* string = tb_null;
- do
- {
- // make string
- string = tb_oc_string_init_base();
- tb_assert_and_check_break(string);
-
- // init str
- if (!tb_string_init(&string->str)) break;
-
- // copy string
- if (cstr) tb_string_cstrcpy(&string->str, cstr);
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- tb_oc_string_exit((tb_object_ref_t)string);
- string = tb_null;
- }
-
- // ok?
- return (tb_object_ref_t)string;
-}
-tb_object_ref_t tb_oc_string_init_from_str(tb_string_ref_t str)
-{
- // done
- tb_bool_t ok = tb_false;
- tb_oc_string_t* string = tb_null;
- do
- {
- // make string
- string = tb_oc_string_init_base();
- tb_assert_and_check_break(string);
-
- // init str
- if (!tb_string_init(&string->str)) break;
-
- // copy string
- if (str) tb_string_strcpy(&string->str, str);
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- tb_oc_string_exit((tb_object_ref_t)string);
- string = tb_null;
- }
-
- // ok?
- return (tb_object_ref_t)string;
-}
-tb_char_t const* tb_oc_string_cstr(tb_object_ref_t object)
-{
- // check
- tb_oc_string_t* string = tb_oc_string_cast(object);
- tb_assert_and_check_return_val(string, tb_null);
-
- // cstr
- return tb_string_cstr(&string->str);
-}
-tb_size_t tb_oc_string_cstr_set(tb_object_ref_t object, tb_char_t const* cstr)
-{
- // check
- tb_oc_string_t* string = tb_oc_string_cast(object);
- tb_assert_and_check_return_val(string && cstr, 0);
-
- // copy string
- tb_string_cstrcpy(&string->str, cstr);
-
- // ok?
- return tb_string_size(&string->str);
-}
-tb_size_t tb_oc_string_size(tb_object_ref_t object)
-{
- // check
- tb_oc_string_t* string = tb_oc_string_cast(object);
- tb_assert_and_check_return_val(string, 0);
-
- // size
- return tb_string_size(&string->str);
-}
-
diff --git a/core/src/tbox/src/tbox/object/string.h b/core/src/tbox/src/tbox/object/string.h
deleted file mode 100644
index ce4e6c4eb..000000000
--- a/core/src/tbox/src/tbox/object/string.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file string.h
- * @ingroup object
- *
- */
-#ifndef TB_OBJECT_STRING_H
-#define TB_OBJECT_STRING_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init string from c-string
- *
- * @param cstr the c-string
- *
- * @return the string object
- */
-tb_object_ref_t tb_oc_string_init_from_cstr(tb_char_t const* cstr);
-
-/*! init string from string
- *
- * @param str the string
- *
- * @return the string object
- */
-tb_object_ref_t tb_oc_string_init_from_str(tb_string_ref_t str);
-
-/*! the c-string
- *
- * @param string the string object
- *
- * @return the c-string
- */
-tb_char_t const* tb_oc_string_cstr(tb_object_ref_t string);
-
-/*! set the c-string
- *
- * @param string the string object
- * @param cstr the c-string
- *
- * @return the string size
- */
-tb_size_t tb_oc_string_cstr_set(tb_object_ref_t string, tb_char_t const* cstr);
-
-/*! the string size
- *
- * @param string the string object
- *
- * @return the string size
- */
-tb_size_t tb_oc_string_size(tb_object_ref_t string);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
-
diff --git a/core/src/tbox/src/tbox/regex/impl/impl.h b/core/src/tbox/src/tbox/regex/impl/impl.h
deleted file mode 100644
index e7d53b619..000000000
--- a/core/src/tbox/src/tbox/regex/impl/impl.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file prefix.h
- *
- */
-#ifndef TB_REGEX_IMPL_H
-#define TB_REGEX_IMPL_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * private implementation
- */
-static tb_void_t tb_regex_match_exit(tb_element_ref_t element, tb_pointer_t buff)
-{
- // check
- tb_regex_match_ref_t match = (tb_regex_match_ref_t)buff;
- tb_assert_and_check_return(match);
-
- // exit it
- if (match->cstr) tb_free(match->cstr);
- match->cstr = tb_null;
- match->size = 0;
-}
-
-#endif
diff --git a/core/src/tbox/src/tbox/regex/impl/pcre.c b/core/src/tbox/src/tbox/regex/impl/pcre.c
deleted file mode 100644
index d8165e066..000000000
--- a/core/src/tbox/src/tbox/regex/impl/pcre.c
+++ /dev/null
@@ -1,357 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file pcre.c
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-#include <pcre.h>
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the regex type
-typedef struct __tb_regex_t
-{
- // the code
- pcre* code;
-
- // the results
- tb_vector_ref_t results;
-
- // the mode
- tb_size_t mode;
-
- // the ovector data
- tb_int_t* ovector_data;
-
- // the ovector maxn
- tb_size_t ovector_maxn;
-
- // the buffer data
- tb_char_t* buffer_data;
-
- // the buffer maxn
- tb_size_t buffer_maxn;
-
-}tb_regex_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_regex_ref_t tb_regex_init(tb_char_t const* pattern, tb_size_t mode)
-{
- // check
- tb_assert_and_check_return_val(pattern, tb_null);
-
- // done
- tb_bool_t ok = tb_false;
- tb_regex_t* regex = tb_null;
- do
- {
- // make regex
- regex = (tb_regex_t*)tb_malloc0_type(tb_regex_t);
- tb_assert_and_check_break(regex);
-
- // init options
- tb_int_t options = 0;//PCRE_UTF8;
- if (mode & TB_REGEX_MODE_CASELESS) options |= PCRE_CASELESS;
- if (mode & TB_REGEX_MODE_MULTILINE) options |= PCRE_MULTILINE;
-#ifndef __tb_debug__
- options |= 0;//PCRE_NO_UTF_CHECK;
-#endif
-
- // init code
- tb_char_t const* errorstring = tb_null;
- tb_int_t erroroffset = 0;
- regex->code = pcre_compile(pattern, options, &errorstring, &erroroffset, tb_null);
- if (!regex->code)
- {
- // trace
- tb_trace_d("compile failed at offset %ld: %s\n", (tb_long_t)erroroffset, errorstring);
-
- // end
- break;
- }
-
- // save mode
- regex->mode = mode;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (regex) tb_regex_exit((tb_regex_ref_t)regex);
- regex = tb_null;
- }
-
- // ok?
- return (tb_regex_ref_t)regex;
-}
-tb_void_t tb_regex_exit(tb_regex_ref_t self)
-{
- // check
- tb_regex_t* regex = (tb_regex_t*)self;
- tb_assert_and_check_return(regex);
-
- // exit buffer data
- if (regex->buffer_data) tb_free(regex->buffer_data);
- regex->buffer_data = tb_null;
- regex->buffer_maxn = 0;
-
- // exit ovector
- if (regex->ovector_data) tb_free(regex->ovector_data);
- regex->ovector_data = tb_null;
- regex->ovector_maxn = 0;
-
- // exit results
- if (regex->results) tb_vector_exit(regex->results);
- regex->results = tb_null;
-
- // exit code
- if (regex->code) pcre_free(regex->code);
- regex->code = tb_null;
-
- // exit it
- tb_free(regex);
-}
-tb_long_t tb_regex_match(tb_regex_ref_t self, tb_char_t const* cstr, tb_size_t size, tb_size_t start, tb_size_t* plength, tb_vector_ref_t* presults)
-{
- // check
- tb_regex_t* regex = (tb_regex_t*)self;
- tb_assert_and_check_return_val(regex && regex->code && cstr, -1);
-
- // done
- tb_long_t ok = -1;
- do
- {
- // clear length first
- if (plength) *plength = 0;
-
- // end?
- tb_check_break(start < size);
-
- // init options
-#ifdef __tb_debug__
- tb_uint32_t options = 0;
-#else
- tb_uint32_t options = 0;//PCRE_NO_UTF_CHECK;
-#endif
-
- // init ovector
- if (!regex->ovector_data)
- {
- regex->ovector_maxn = 3 * 16;
- regex->ovector_data = (tb_int_t*)tb_malloc_bytes(sizeof(tb_int_t) * regex->ovector_maxn);
- }
- tb_assert_and_check_break(regex->ovector_data);
-
- // match it
- tb_long_t count = -1;
- while (!(count = pcre_exec(regex->code, tb_null, cstr, size, start, options, regex->ovector_data, regex->ovector_maxn)))
- {
- // grow ovector
- regex->ovector_maxn <<= 1;
- regex->ovector_data = (tb_int_t*)tb_ralloc_bytes(regex->ovector_data, sizeof(tb_int_t) * regex->ovector_maxn);
- tb_assert_and_check_break(regex->ovector_data);
- }
- if (count < 0)
- {
- // no match?
- tb_check_break(count != PCRE_ERROR_NOMATCH);
-
- // trace
- tb_trace_d("match failed at offset %lu: error: %ld\n", start, count);
-
- // end
- break;
- }
-
- // check
- tb_assertf_and_check_break(count, "ovector has not enough space!");
-
- // get the match offset and length
- tb_int_t const* ovector = regex->ovector_data;
- tb_size_t offset = (tb_size_t)ovector[0];
- tb_size_t length = (tb_size_t)ovector[1] - ovector[0];
- tb_assert_and_check_break(offset + length <= size);
-
- // trace
- tb_trace_d("matched count: %lu, offset: %lu, length: %lu", count, offset, length);
-
- // save results
- if (presults)
- {
- // init results if not exists
- tb_vector_ref_t results = *presults;
- if (!results)
- {
- // init it
- if (!regex->results) regex->results = tb_vector_init(16, tb_element_mem(sizeof(tb_regex_match_t), tb_regex_match_exit, tb_null));
-
- // save it
- *presults = results = regex->results;
- }
- tb_assert_and_check_break(results);
-
- // clear it first
- tb_vector_clear(results);
-
- // done
- tb_long_t i = 0;
- tb_regex_match_t entry;
- for (i = 0; i < count; i++)
- {
- // get substring offset and length
- tb_size_t substr_offset = ovector[i << 1];
- tb_size_t substr_length = ovector[(i << 1) + 1] - ovector[i << 1];
- tb_assert_and_check_break(substr_offset + substr_length <= size);
-
- // make match entry
- entry.cstr = tb_strndup(cstr + substr_offset, substr_length);
- entry.size = substr_length;
- entry.start = substr_offset;
- tb_assert_and_check_break(entry.cstr);
-
- // trace
- tb_trace_d(" matched: [%lu, %lu]: %s", entry.start, entry.size, entry.cstr);
-
- // append it
- tb_vector_insert_tail(results, &entry);
- }
- tb_assert_and_check_break(i == count);
- }
-
- // save length
- if (plength) *plength = length;
-
- // ok
- ok = offset;
-
- } while (0);
-
- // ok?
- return ok;
-}
-tb_char_t const* tb_regex_replace(tb_regex_ref_t self, tb_char_t const* cstr, tb_size_t size, tb_size_t start, tb_char_t const* replace_cstr, tb_size_t replace_size, tb_size_t* plength)
-{
- // check
- tb_regex_t* regex = (tb_regex_t*)self;
- tb_assert_and_check_return_val(regex && cstr && replace_cstr, tb_null);
-
- // done
- tb_char_t const* result = tb_null;
- do
- {
- // clear length first
- if (plength) *plength = 0;
-
- // end?
- tb_check_break(start < size);
-
- // init buffer
- if (!regex->buffer_data)
- {
- regex->buffer_maxn = tb_max(size + replace_size + 64, 256);
- regex->buffer_data = tb_malloc_cstr(regex->buffer_maxn);
- }
- tb_assert_and_check_break(regex->buffer_data);
-
- // copy cstr
- tb_memcpy(regex->buffer_data, cstr, size);
- regex->buffer_data[size] = '\0';
-
- // done
- tb_size_t count = 0;
- tb_long_t suboffset = start;
- tb_size_t sublength = 0;
- tb_size_t length = 0;
- tb_vector_ref_t results = tb_null;
- while ((suboffset = tb_regex_match(self, regex->buffer_data, size, suboffset + sublength, &sublength, &results)) >= 0 && results)
- {
- // trace
- tb_trace_d("replace: match: [%lu, %lu]", suboffset, sublength);
-
- // calculate substring end
- tb_size_t subend = suboffset + sublength;
- tb_assert_and_check_break(subend <= size);
-
- // update length
- length = size - sublength + replace_size;
-
- // grow buffer
- if (regex->buffer_maxn < length)
- {
- regex->buffer_maxn = tb_max(regex->buffer_maxn << 1, length);
- regex->buffer_data = tb_ralloc_cstr(regex->buffer_data, regex->buffer_maxn + 1);
- }
- tb_assert_and_check_break(regex->buffer_data);
-
- // replace this match
- if (subend < size) tb_memmov(regex->buffer_data + suboffset + replace_size, regex->buffer_data + subend, size - subend);
- tb_memcpy(regex->buffer_data + suboffset, replace_cstr, replace_size);
- regex->buffer_data[length] = '\0';
-
- // trace
- tb_trace_d("replace: => %s", regex->buffer_data);
-
- // update matched count
- count++;
-
- // global replace?
- tb_check_break(regex->mode & TB_REGEX_MODE_GLOBAL);
-
- // update size
- size = length;
- sublength = replace_size;
- }
-
- // check
- tb_check_break(count);
- tb_assert_and_check_break(length < regex->buffer_maxn);
-
- // end
- regex->buffer_data[length] = '\0';
-
- // trace
- tb_trace_d(" replace: [%lu]: %s", length, regex->buffer_data);
-
- // save length
- if (plength) *plength = length;
-
- // ok
- result = (tb_char_t const*)regex->buffer_data;
-
- } while (0);
-
- // ok?
- return result;
-}
diff --git a/core/src/tbox/src/tbox/regex/impl/pcre2.c b/core/src/tbox/src/tbox/regex/impl/pcre2.c
deleted file mode 100644
index 1ba59698e..000000000
--- a/core/src/tbox/src/tbox/regex/impl/pcre2.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file pcre2.c
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-#include <pcre2.h>
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the regex type
-typedef struct __tb_regex_t
-{
- // the code
- pcre2_code* code;
-
- // the match data
- pcre2_match_data* match_data;
-
- // the results
- tb_vector_ref_t results;
-
- // the mode
- tb_size_t mode;
-
- // the buffer data
- PCRE2_UCHAR* buffer_data;
-
- // the buffer maxn
- tb_size_t buffer_maxn;
-
-}tb_regex_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_regex_ref_t tb_regex_init(tb_char_t const* pattern, tb_size_t mode)
-{
- // check
- tb_assert_and_check_return_val(pattern, tb_null);
-
- // done
- tb_bool_t ok = tb_false;
- tb_regex_t* regex = tb_null;
- do
- {
- // make regex
- regex = (tb_regex_t*)tb_malloc0_type(tb_regex_t);
- tb_assert_and_check_break(regex);
-
- // init options
- tb_uint32_t options = PCRE2_UTF;
- if (mode & TB_REGEX_MODE_CASELESS) options |= PCRE2_CASELESS;
- if (mode & TB_REGEX_MODE_MULTILINE) options |= PCRE2_MULTILINE;
-#ifndef __tb_debug__
- options |= PCRE2_NO_UTF_CHECK;
-#endif
-
- // init code
- tb_int_t errornumber;
- PCRE2_SIZE erroroffset;
- regex->code = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, options, &errornumber, &erroroffset, tb_null);
- if (!regex->code)
- {
-#if defined(__tb_debug__) && !defined(TB_CONFIG_OS_WINDOWS) // FIXME: _sprintf undefined link error for vs2015 on windows
- // get error info
- PCRE2_UCHAR info[256];
- pcre2_get_error_message(errornumber, info, sizeof(info));
-
- // trace
- tb_trace_d("compile failed at offset %ld: %s\n", (tb_long_t)erroroffset, info);
-#endif
-
- // end
- break;
- }
-
- // init match data
- regex->match_data = pcre2_match_data_create_from_pattern(regex->code, tb_null);
- tb_assert_and_check_break(regex->match_data);
-
- // save mode
- regex->mode = mode;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (regex) tb_regex_exit((tb_regex_ref_t)regex);
- regex = tb_null;
- }
-
- // ok?
- return (tb_regex_ref_t)regex;
-}
-tb_void_t tb_regex_exit(tb_regex_ref_t self)
-{
- // check
- tb_regex_t* regex = (tb_regex_t*)self;
- tb_assert_and_check_return(regex);
-
- // exit buffer
- if (regex->buffer_data) tb_free(regex->buffer_data);
- regex->buffer_data = tb_null;
- regex->buffer_maxn = 0;
-
- // exit results
- if (regex->results) tb_vector_exit(regex->results);
- regex->results = tb_null;
-
- // exit match data
- if (regex->match_data) pcre2_match_data_free(regex->match_data);
- regex->match_data = tb_null;
-
- // exit code
- if (regex->code) pcre2_code_free(regex->code);
- regex->code = tb_null;
-
- // exit it
- tb_free(regex);
-}
-tb_long_t tb_regex_match(tb_regex_ref_t self, tb_char_t const* cstr, tb_size_t size, tb_size_t start, tb_size_t* plength, tb_vector_ref_t* presults)
-{
- // check
- tb_regex_t* regex = (tb_regex_t*)self;
- tb_assert_and_check_return_val(regex && regex->code && regex->match_data && cstr, -1);
-
- // done
- tb_long_t ok = -1;
- do
- {
- // clear length first
- if (plength) *plength = 0;
-
- // end?
- tb_check_break(start < size);
-
- // init options
-#ifdef __tb_debug__
- tb_uint32_t options = 0;
-#else
- tb_uint32_t options = PCRE2_NO_UTF_CHECK;
-#endif
-
- // match it
- tb_long_t count = pcre2_match(regex->code, (PCRE2_SPTR)cstr, (PCRE2_SIZE)size, (PCRE2_SIZE)start, options, regex->match_data, tb_null);
- if (count < 0)
- {
- // no match?
- tb_check_break(count != PCRE2_ERROR_NOMATCH);
-
-#if defined(__tb_debug__) && !defined(TB_CONFIG_OS_WINDOWS)
- // get error info
- PCRE2_UCHAR info[256];
- pcre2_get_error_message(count, info, sizeof(info));
-
- // trace
- tb_trace_d("match failed at offset %lu: error: %ld, %s\n", start, count, info);
-#endif
-
- // end
- break;
- }
-
- // check
- tb_assertf_and_check_break(count, "ovector has not enough space!");
-
- // get output vector
- PCRE2_SIZE* ovector = pcre2_get_ovector_pointer(regex->match_data);
- tb_assert_and_check_break(ovector);
-
- // get the match offset and length
- tb_size_t offset = (tb_size_t)ovector[0];
- tb_size_t length = (tb_size_t)ovector[1] - ovector[0];
- tb_assert_and_check_break(offset + length <= size);
-
- // trace
- tb_trace_d("matched count: %lu, offset: %lu, length: %lu", count, offset, length);
-
- // save results
- if (presults)
- {
- // init results if not exists
- tb_vector_ref_t results = *presults;
- if (!results)
- {
- // init it
- if (!regex->results) regex->results = tb_vector_init(16, tb_element_mem(sizeof(tb_regex_match_t), tb_regex_match_exit, tb_null));
-
- // save it
- *presults = results = regex->results;
- }
- tb_assert_and_check_break(results);
-
- // clear it first
- tb_vector_clear(results);
-
- // done
- tb_long_t i = 0;
- tb_regex_match_t entry;
- for (i = 0; i < count; i++)
- {
- // get substring offset and length
- tb_size_t substr_offset = ovector[i << 1];
- tb_size_t substr_length = ovector[(i << 1) + 1] - ovector[i << 1];
- tb_assert_and_check_break(substr_offset + substr_length <= size);
-
- // make match entry
- entry.cstr = tb_strndup(cstr + substr_offset, substr_length);
- entry.size = substr_length;
- entry.start = substr_offset;
- tb_assert_and_check_break(entry.cstr);
-
- // trace
- tb_trace_d(" matched: [%lu, %lu]: %s", entry.start, entry.size, entry.cstr);
-
- // append it
- tb_vector_insert_tail(results, &entry);
- }
- tb_assert_and_check_break(i == count);
- }
-
- // save length
- if (plength) *plength = length;
-
- // ok
- ok = offset;
-
- } while (0);
-
- // ok?
- return ok;
-}
-tb_char_t const* tb_regex_replace(tb_regex_ref_t self, tb_char_t const* cstr, tb_size_t size, tb_size_t start, tb_char_t const* replace_cstr, tb_size_t replace_size, tb_size_t* plength)
-{
- // check
- tb_regex_t* regex = (tb_regex_t*)self;
- tb_assert_and_check_return_val(regex && regex->code && cstr && replace_cstr, tb_null);
-
- // done
- tb_char_t const* result = tb_null;
- do
- {
- // clear length first
- if (plength) *plength = 0;
-
- // end?
- tb_check_break(start < size);
-
- // init options
-#ifdef __tb_debug__
- tb_uint32_t options = 0;
-#else
- tb_uint32_t options = PCRE2_NO_UTF_CHECK;
-#endif
- if (regex->mode & TB_REGEX_MODE_GLOBAL) options |= PCRE2_SUBSTITUTE_GLOBAL;
-
- // init buffer
- if (!regex->buffer_data)
- {
- regex->buffer_maxn = tb_max(size + replace_size + 64, 256);
- regex->buffer_data = (PCRE2_UCHAR*)tb_malloc_bytes(regex->buffer_maxn);
- }
- tb_assert_and_check_break(regex->buffer_data);
-
- // done
- tb_long_t ok = -1;
- PCRE2_SIZE length = 0;
- while (1)
- {
- // replace it
- length = (PCRE2_SIZE)regex->buffer_maxn;
- ok = pcre2_substitute(regex->code, (PCRE2_SPTR)cstr, (PCRE2_SIZE)size, (PCRE2_SIZE)start, options, tb_null, tb_null, (PCRE2_SPTR)replace_cstr, (PCRE2_SIZE)replace_size, regex->buffer_data, &length);
-
- // no space?
- if (ok == PCRE2_ERROR_NOMEMORY)
- {
- // grow buffer
- regex->buffer_maxn <<= 1;
- regex->buffer_data = (PCRE2_UCHAR*)tb_ralloc_bytes(regex->buffer_data, regex->buffer_maxn);
- tb_assert_and_check_break(regex->buffer_data);
- }
- // failed
- else if (ok < 0)
- {
-#if defined(__tb_debug__) && !defined(TB_CONFIG_OS_WINDOWS)
- // get error info
- PCRE2_UCHAR info[256];
- pcre2_get_error_message(ok, info, sizeof(info));
-
- // trace
- tb_trace_d("replace failed at offset %lu: error: %ld, %s\n", start, ok, info);
-#endif
-
- // end
- break;
- }
- else break;
- }
-
- // check
- tb_check_break(ok > 0);
- tb_assert_and_check_break(length < regex->buffer_maxn);
-
- // end
- regex->buffer_data[length] = '\0';
-
- // trace
- tb_trace_d(" replace: [%lu]: %s", length, regex->buffer_data);
-
- // save length
- if (plength) *plength = (tb_size_t)length;
-
- // ok
- result = (tb_char_t const*)regex->buffer_data;
-
- } while (0);
-
- // ok?
- return result;
-}
diff --git a/core/src/tbox/src/tbox/regex/impl/prefix.h b/core/src/tbox/src/tbox/regex/impl/prefix.h
deleted file mode 100644
index dc39cb8ea..000000000
--- a/core/src/tbox/src/tbox/regex/impl/prefix.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file prefix.h
- *
- */
-#ifndef TB_REGEX_IMPL_PREFIX_H
-#define TB_REGEX_IMPL_PREFIX_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "../prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-
-#endif
diff --git a/core/src/tbox/src/tbox/regex/prefix.h b/core/src/tbox/src/tbox/regex/prefix.h
deleted file mode 100644
index aa3435a69..000000000
--- a/core/src/tbox/src/tbox/regex/prefix.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file prefix.h
- * @ingroup regex
- *
- */
-#ifndef TB_REGEX_PREFIX_H
-#define TB_REGEX_PREFIX_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "../prefix.h"
-#include "../libc/libc.h"
-#include "../container/container.h"
-
-
-#endif
diff --git a/core/src/tbox/src/tbox/regex/regex.c b/core/src/tbox/src/tbox/regex/regex.c
deleted file mode 100644
index 4b516972d..000000000
--- a/core/src/tbox/src/tbox/regex/regex.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file regex.c
- * @ingroup regex
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "regex"
-#define TB_TRACE_MODULE_DEBUG (1)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "regex.h"
-#include "impl/impl.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-#if defined(TB_CONFIG_PACKAGE_HAVE_PCRE2)
-# include "impl/pcre2.c"
-#elif defined(TB_CONFIG_PACKAGE_HAVE_PCRE)
-# include "impl/pcre.c"
-#elif defined(TB_CONFIG_POSIX_HAVE_REGCOMP) \
- && defined(TB_CONFIG_POSIX_HAVE_REGEXEC)
-# include "../platform/posix/regex.c"
-#else
-tb_regex_ref_t tb_regex_init(tb_char_t const* pattern, tb_size_t mode)
-{
- tb_assert_noimpl();
- return tb_null;
-}
-tb_void_t tb_regex_exit(tb_regex_ref_t regex)
-{
- tb_assert_noimpl();
-}
-tb_long_t tb_regex_match(tb_regex_ref_t regex, tb_char_t const* cstr, tb_size_t size, tb_size_t start, tb_size_t* plength, tb_vector_ref_t* presults)
-{
- tb_assert_noimpl();
- return -1;
-}
-tb_char_t const* tb_regex_replace(tb_regex_ref_t regex, tb_char_t const* cstr, tb_size_t size, tb_size_t start, tb_char_t const* replace_cstr, tb_size_t replace_size, tb_size_t* plength)
-{
- tb_assert_noimpl();
- return tb_null;
-}
-#endif
-tb_long_t tb_regex_match_cstr(tb_regex_ref_t regex, tb_char_t const* cstr, tb_size_t start, tb_size_t* plength, tb_vector_ref_t* presults)
-{
- // check
- tb_assert_and_check_return_val(cstr, -1);
-
- // done
- return tb_regex_match(regex, cstr, tb_strlen(cstr), start, plength, presults);
-}
-tb_vector_ref_t tb_regex_match_simple(tb_regex_ref_t regex, tb_char_t const* cstr)
-{
- // check
- tb_assert_and_check_return_val(cstr, tb_null);
-
- // done
- tb_vector_ref_t results = tb_null;
- return tb_regex_match(regex, cstr, tb_strlen(cstr), 0, tb_null, &results) >= 0? results : tb_null;
-}
-tb_char_t const* tb_regex_replace_cstr(tb_regex_ref_t regex, tb_char_t const* cstr, tb_size_t start, tb_char_t const* replace_cstr, tb_size_t* plength)
-{
- // check
- tb_assert_and_check_return_val(cstr && replace_cstr, tb_null);
-
- // done
- return tb_regex_replace(regex, cstr, tb_strlen(cstr), start, replace_cstr, tb_strlen(replace_cstr), plength);
-}
-tb_char_t const* tb_regex_replace_simple(tb_regex_ref_t regex, tb_char_t const* cstr, tb_char_t const* replace_cstr)
-{
- // check
- tb_assert_and_check_return_val(cstr && replace_cstr, tb_null);
-
- // done
- return tb_regex_replace(regex, cstr, tb_strlen(cstr), 0, replace_cstr, tb_strlen(replace_cstr), tb_null);
-}
-tb_long_t tb_regex_match_done(tb_char_t const* pattern, tb_size_t mode, tb_char_t const* cstr, tb_size_t size, tb_size_t start, tb_size_t* plength, tb_vector_ref_t* presults)
-{
- // clear results first
- if (presults) *presults = tb_null;
-
- // init regex
- tb_long_t ok = -1;
- tb_regex_ref_t regex = tb_regex_init(pattern, mode);
- if (regex)
- {
- // init results
- tb_vector_ref_t results = tb_vector_init(16, tb_element_mem(sizeof(tb_regex_match_t), tb_regex_match_exit, tb_null));
- if (results)
- {
- // match regex
- ok = tb_regex_match(regex, cstr, size, start, plength, &results);
-
- // ok?
- if (ok >= 0)
- {
- // save results
- if (presults)
- {
- *presults = results;
- results = tb_null;
- }
- }
-
- // exit results
- if (results) tb_vector_exit(results);
- results = tb_null;
- }
-
- // exit regex
- tb_regex_exit(regex);
- }
-
- // ok?
- return ok;
-}
-tb_long_t tb_regex_match_done_cstr(tb_char_t const* pattern, tb_size_t mode, tb_char_t const* cstr, tb_size_t start, tb_size_t* plength, tb_vector_ref_t* presults)
-{
- // check
- tb_assert_and_check_return_val(cstr, -1);
-
- // done
- return tb_regex_match_done(pattern, mode, cstr, tb_strlen(cstr), start, plength, presults);
-}
-tb_vector_ref_t tb_regex_match_done_simple(tb_char_t const* pattern, tb_size_t mode, tb_char_t const* cstr)
-{
- // check
- tb_assert_and_check_return_val(cstr, tb_null);
-
- // done
- tb_vector_ref_t results = tb_null;
- return tb_regex_match_done(pattern, mode, cstr, tb_strlen(cstr), 0, tb_null, &results) >= 0? results : tb_null;
-}
-tb_char_t const* tb_regex_replace_done(tb_char_t const* pattern, tb_size_t mode, tb_char_t const* cstr, tb_size_t size, tb_size_t start, tb_char_t const* replace_cstr, tb_size_t replace_size, tb_size_t* plength)
-{
- // clear length first
- if (plength) *plength = 0;
-
- // init regex
- tb_char_t* result = tb_null;
- tb_regex_ref_t regex = tb_regex_init(pattern, mode);
- if (regex)
- {
- // replace regex
- tb_size_t result_size = 0;
- tb_char_t const* result_cstr = tb_regex_replace(regex, cstr, size, start, replace_cstr, replace_size, &result_size);
- if (result_cstr && result_size)
- {
- // save result
- result = tb_strndup(result_cstr, result_size);
- if (result)
- {
- // save length
- if (plength) *plength = result_size;
- }
- }
-
- // exit regex
- tb_regex_exit(regex);
- }
-
- // ok?
- return result;
-}
-tb_char_t const* tb_regex_replace_done_cstr(tb_char_t const* pattern, tb_size_t mode, tb_char_t const* cstr, tb_size_t start, tb_char_t const* replace_cstr, tb_size_t* plength)
-{
- // check
- tb_assert_and_check_return_val(cstr && replace_cstr, tb_null);
-
- // done
- return tb_regex_replace_done(pattern, mode, cstr, tb_strlen(cstr), start, replace_cstr, tb_strlen(replace_cstr), tb_null);
-}
-tb_char_t const* tb_regex_replace_done_simple(tb_char_t const* pattern, tb_size_t mode, tb_char_t const* cstr, tb_char_t const* replace_cstr)
-{
- // check
- tb_assert_and_check_return_val(cstr && replace_cstr, tb_null);
-
- // done
- return tb_regex_replace_done(pattern, mode, cstr, tb_strlen(cstr), 0, replace_cstr, tb_strlen(replace_cstr), tb_null);
-}
diff --git a/core/src/tbox/src/tbox/regex/regex.h b/core/src/tbox/src/tbox/regex/regex.h
deleted file mode 100644
index 973601c7d..000000000
--- a/core/src/tbox/src/tbox/regex/regex.h
+++ /dev/null
@@ -1,422 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file regex.h
- * @defgroup regex
- */
-#ifndef TB_REGEX_H
-#define TB_REGEX_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the regex ref type
-typedef __tb_typeref__(regex);
-
-/// the regex match type
-typedef struct _tb_regex_match_t
-{
- /// the c-string data
- tb_char_t const* cstr;
-
- /// the c-string size
- tb_size_t size;
-
- /// the matched start position
- tb_size_t start;
-
-}tb_regex_match_t, *tb_regex_match_ref_t;
-
-/// the regex mode enum
-typedef enum __tb_regex_mode_e
-{
- TB_REGEX_MODE_NONE = 0 //!< the default mode
-, TB_REGEX_MODE_CASELESS = 1 //!< do caseless matching
-, TB_REGEX_MODE_MULTILINE = 2 //!< ^ and $ match newlines within data
-, TB_REGEX_MODE_GLOBAL = 4 //!< global replace all
-
-}tb_regex_mode_e;
-
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init regex
- *
- * @param pattern the regex pattern
- * @param mode the regex mode, uses the default mode if be zero
- *
- * @return the regex
- */
-tb_regex_ref_t tb_regex_init(tb_char_t const* pattern, tb_size_t mode);
-
-/*! exit regex
- *
- * @param regex the regex
- */
-tb_void_t tb_regex_exit(tb_regex_ref_t regex);
-
-/*! match the given c-string and size by regex
- *
- * @param regex the regex
- * @param cstr the c-string data
- * @param size the c-string size
- * @param start the start position
- * @param plength the matched length pointer, do not get it if be null
- * @param presults the results pointer, only match it if be null
- *
- * @return the matched position, not match: -1
- */
-tb_long_t tb_regex_match(tb_regex_ref_t regex, tb_char_t const* cstr, tb_size_t size, tb_size_t start, tb_size_t* plength, tb_vector_ref_t* presults);
-
-/*! match the given c-string by regex
- *
- * @code
-
- // init regex
- tb_regex_ref_t regex = tb_regex_init("\\w+", 0);
- if (regex)
- {
- // match single
- //
- // results: "hello"
- //
- tb_vector_ref_t results = tb_null;
- if (tb_regex_match_cstr(regex, "hello world", 0, tb_null, &results) >= 0 && results)
- {
- // show results
- tb_for_all_if (tb_regex_match_ref_t, entry, results, entry)
- {
- // trace
- tb_trace_i("cstr: %s, size: %lu, start: %lu", entry->cstr, entry->size, entry->start);
- }
- }
-
- // match global
- //
- // results: "hello"
- // results: "world"
- //
- tb_long_t start = 0;
- tb_size_t length = 0;
- tb_vector_ref_t results = tb_null;
- while ((start = tb_regex_match_cstr(regex, "hello world", start + length, &length, &results)) >= 0 && results)
- {
- // show results
- tb_for_all_if (tb_regex_match_ref_t, entry, results, entry)
- {
- // trace
- tb_trace_i("cstr: %s, size: %lu, start: %lu", entry->cstr, entry->size, entry->start);
- }
- }
-
- // exit regex
- tb_regex_exit(regex);
- }
- * @endcode
- *
- * @param regex the regex
- * @param cstr the c-string
- * @param start the start position
- * @param plength the matched length pointer, do not get it if be null
- * @param presults the results pointer, only match it if be null
- *
- * @return the matched position, not match: -1
- */
-tb_long_t tb_regex_match_cstr(tb_regex_ref_t regex, tb_char_t const* cstr, tb_size_t start, tb_size_t* plength, tb_vector_ref_t* presults);
-
-/*! simply match the given c-string by regex
- *
- * @note only supports single match
- *
- * @code
-
- // init regex
- tb_regex_ref_t regex = tb_regex_init("\\w+", 0);
- if (regex)
- {
- // match single
- //
- // results: "hello"
- //
- tb_vector_ref_t results = tb_regex_match_simple(regex, "hello world");
- if (results)
- {
- // show results
- tb_for_all_if (tb_regex_match_ref_t, entry, results, entry)
- {
- // trace
- tb_trace_i("cstr: %s, size: %lu, start: %lu", entry->cstr, entry->size, entry->start);
- }
- }
-
- // exit regex
- tb_regex_exit(regex);
- }
- * @endcode
- *
- * @param regex the regex
- * @param cstr the c-string
- *
- * @return the matched results
- */
-tb_vector_ref_t tb_regex_match_simple(tb_regex_ref_t regex, tb_char_t const* cstr);
-
-/*! replace the given c-string and size by regex
- *
- * @param regex the regex
- * @param cstr the c-string data
- * @param size the c-string size
- * @param start the start position
- * @param replace_cstr the replacement c-string data
- * @param replace_size the replacement c-string size
- * @param plength the result c-string length pointer, do not get it if be null
- *
- * @return the result c-string
- */
-tb_char_t const* tb_regex_replace(tb_regex_ref_t regex, tb_char_t const* cstr, tb_size_t size, tb_size_t start, tb_char_t const* replace_cstr, tb_size_t replace_size, tb_size_t* plength);
-
-/*! replace the given c-string by regex
- *
- * @param regex the regex
- * @param cstr the c-string data
- * @param start the start position
- * @param replace_cstr the replacement c-string data
- * @param plength the result c-string length pointer, do not get it if be null
- *
- * @return the result c-string
- */
-tb_char_t const* tb_regex_replace_cstr(tb_regex_ref_t regex, tb_char_t const* cstr, tb_size_t start, tb_char_t const* replace_cstr, tb_size_t* plength);
-
-/*! simply replace the given c-string by regex
- *
- * @code
-
- // init regex
- tb_regex_ref_t regex = tb_regex_init("\\w+", 0);
- if (regex)
- {
- // match single
- //
- // results: "hi world"
- //
- tb_char_t const* results = tb_regex_replace_simple(regex, "hello world", "hi");
- if (results)
- {
- // trace
- tb_trace_i("results: %s", results);
- }
-
- // exit regex
- tb_regex_exit(regex);
- }
- * @endcode
- *
- * @param regex the regex
- * @param cstr the c-string data
- * @param replace_cstr the replacement c-string data
- *
- * @return the result c-string
- */
-tb_char_t const* tb_regex_replace_simple(tb_regex_ref_t regex, tb_char_t const* cstr, tb_char_t const* replace_cstr);
-
-/*! match the given c-string and size by the given regex pattern
- *
- * @param pattern the regex pattern
- * @param mode the regex mode, uses the default mode if be zero
- * @param cstr the c-string data
- * @param size the c-string size
- * @param start the start position
- * @param plength the matched length pointer, do not get it if be null
- * @param presults the results pointer, only match it if be null
- * @note we need exit it manually
- *
- * @return the matched position, not match: -1
- */
-tb_long_t tb_regex_match_done(tb_char_t const* pattern, tb_size_t mode, tb_char_t const* cstr, tb_size_t size, tb_size_t start, tb_size_t* plength, tb_vector_ref_t* presults);
-
-/*! match the given c-string by the given regex pattern
- *
- * @code
-
- // match single
- //
- // results: "hello"
- //
- tb_vector_ref_t results = tb_null;
- if (tb_regex_match_done_cstr("\\w+", 0, "hello world", 0, tb_null, &results) >= 0 && results)
- {
- // show results
- tb_for_all_if (tb_regex_match_ref_t, entry, results, entry)
- {
- // trace
- tb_trace_i("cstr: %s, size: %lu, start: %lu", entry->cstr, entry->size, entry->start);
- }
-
- // exit results
- tb_vector_exit(results);
- }
-
- // match global
- //
- // results: "hello"
- // results: "world"
- //
- tb_long_t start = 0;
- tb_size_t length = 0;
- tb_vector_ref_t results = tb_null;
- while ((start = tb_regex_match_done_cstr("\\w+", 0, "hello world", start + length, &length, &results)) >= 0 && results)
- {
- // show results
- tb_for_all_if (tb_regex_match_ref_t, entry, results, entry)
- {
- // trace
- tb_trace_i("cstr: %s, size: %lu, start: %lu", entry->cstr, entry->size, entry->start);
- }
-
- // exit results
- tb_vector_exit(results);
- }
-
- * @endcode
- *
- * @param pattern the regex pattern
- * @param mode the regex mode, uses the default mode if be zero
- * @param cstr the c-string data
- * @param start the start position
- * @param plength the matched length pointer, do not get it if be null
- * @param presults the results pointer, only match it if be null
- * @note we need exit it manually
- *
- * @return the matched position, not match: -1
- */
-tb_long_t tb_regex_match_done_cstr(tb_char_t const* pattern, tb_size_t mode, tb_char_t const* cstr, tb_size_t start, tb_size_t* plength, tb_vector_ref_t* presults);
-
-/*! simply match the given c-string by the given regex pattern
- *
- * @note only supports single match
- *
- * @code
-
- // match single
- //
- // results: "hello"
- //
- tb_vector_ref_t results = tb_regex_match_done_simple("\\w+", 0, "hello world");
- if (results)
- {
- // show results
- tb_for_all_if (tb_regex_match_ref_t, entry, results, entry)
- {
- // trace
- tb_trace_i("cstr: %s, size: %lu, start: %lu", entry->cstr, entry->size, entry->start);
- }
-
- // exit results
- tb_vector_exit(results);
- }
-
- * @endcode
- *
- * @param pattern the regex pattern
- * @param mode the regex mode, uses the default mode if be zero
- * @param cstr the c-string data
- *
- * @return the matched results, we need exit it manually
- */
-tb_vector_ref_t tb_regex_match_done_simple(tb_char_t const* pattern, tb_size_t mode, tb_char_t const* cstr);
-
-/*! replace the given c-string and size by the given regex pattern
- *
- * @param pattern the regex pattern
- * @param mode the regex mode, uses the default mode if be zero
- * @param cstr the c-string data
- * @param size the c-string size
- * @param start the start position
- * @param replace_cstr the replacement c-string data
- * @param replace_size the replacement c-string size
- * @param plength the result c-string length pointer, do not get it if be null
- *
- * @return the result c-string
- */
-tb_char_t const* tb_regex_replace_done(tb_char_t const* pattern, tb_size_t mode, tb_char_t const* cstr, tb_size_t size, tb_size_t start, tb_char_t const* replace_cstr, tb_size_t replace_size, tb_size_t* plength);
-
-/*! replace the given c-string by the given regex pattern
- *
- * @param pattern the regex pattern
- * @param mode the regex mode, uses the default mode if be zero
- * @param cstr the c-string data
- * @param start the start position
- * @param replace_cstr the replacement c-string data
- * @param plength the result c-string length pointer, do not get it if be null
- *
- * @return the result c-string
- */
-tb_char_t const* tb_regex_replace_done_cstr(tb_char_t const* pattern, tb_size_t mode, tb_char_t const* cstr, tb_size_t start, tb_char_t const* replace_cstr, tb_size_t* plength);
-
-/*! simply replace the given c-string by the given regex pattern
- *
- * @code
-
- // replace single
- //
- // results: "hi world"
- //
- tb_char_t const* results = tb_regex_replace_done_simple("\\w+", 0, "hello world", "hi");
- if (results)
- {
- // trace
- tb_trace_i("results: %s", results);
-
- // exit results
- tb_free(results);
- }
-
- * @endcode
- *
- * @param pattern the regex pattern
- * @param mode the regex mode, uses the default mode if be zero
- * @param cstr the c-string data
- * @param replace_cstr the replacement c-string data
- *
- * @return the result c-string, @note we need free it manually
- */
-tb_char_t const* tb_regex_replace_done_simple(tb_char_t const* pattern, tb_size_t mode, tb_char_t const* cstr, tb_char_t const* replace_cstr);
-
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/tbox.c b/core/src/tbox/src/tbox/tbox.c
index ad41ee3c0..51a139aac 100644
--- a/core/src/tbox/src/tbox/tbox.c
+++ b/core/src/tbox/src/tbox/tbox.c
@@ -30,7 +30,6 @@
#include "libc/impl/impl.h"
#include "libm/impl/impl.h"
#include "math/impl/impl.h"
-#include "object/impl/impl.h"
#include "memory/impl/impl.h"
#include "network/impl/impl.h"
#include "platform/impl/impl.h"
diff --git a/core/src/tbox/src/tbox/tbox.h b/core/src/tbox/src/tbox/tbox.h
index 2c3d85f5e..69c63073a 100644
--- a/core/src/tbox/src/tbox/tbox.h
+++ b/core/src/tbox/src/tbox/tbox.h
@@ -30,25 +30,19 @@
*/
#include "prefix.h"
#include "zip/zip.h"
-#include "xml/xml.h"
-#include "asio/asio.h"
#include "libm/libm.h"
#include "libc/libc.h"
#include "math/math.h"
#include "hash/hash.h"
#include "utils/utils.h"
-#include "regex/regex.h"
-#include "object/object.h"
#include "memory/memory.h"
#include "stream/stream.h"
#include "string/string.h"
#include "network/network.h"
#include "charset/charset.h"
#include "platform/platform.h"
-#include "database/database.h"
#include "algorithm/algorithm.h"
#include "container/container.h"
-#include "coroutine/coroutine.h"
/* //////////////////////////////////////////////////////////////////////////////////////
* extern
diff --git a/core/src/tbox/src/tbox/xml/node.c b/core/src/tbox/src/tbox/xml/node.c
deleted file mode 100644
index 5d56c1429..000000000
--- a/core/src/tbox/src/tbox/xml/node.c
+++ /dev/null
@@ -1,466 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file node.c
- * @ingroup xml
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "xml"
-#define TB_TRACE_MODULE_DEBUG (1)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "node.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_xml_node_ref_t tb_xml_node_init_element(tb_char_t const* name)
-{
- // check
- tb_assert_and_check_return_val(name, tb_null);
-
- // make node
- tb_xml_node_ref_t node = (tb_xml_node_ref_t)tb_malloc0_type(tb_xml_element_t);
- tb_assert_and_check_return_val(node, tb_null);
-
- // init
- node->type = TB_XML_NODE_TYPE_ELEMENT;
- tb_string_init(&node->name);
- tb_string_init(&node->data);
- tb_string_cstrcpy(&node->name, name);
-
- // ok
- return node;
-}
-tb_xml_node_ref_t tb_xml_node_init_text(tb_char_t const* data)
-{
- // make node
- tb_xml_node_ref_t node = (tb_xml_node_ref_t)tb_malloc0_type(tb_xml_text_t);
- tb_assert_and_check_return_val(node, tb_null);
-
- // init
- node->type = TB_XML_NODE_TYPE_TEXT;
- tb_string_init(&node->name);
- tb_string_init(&node->data);
- tb_string_cstrcpy(&node->name, "#text");
- if (data) tb_string_cstrcpy(&node->data, data);
-
- // ok
- return node;
-}
-tb_xml_node_ref_t tb_xml_node_init_cdata(tb_char_t const* cdata)
-{
- // make node
- tb_xml_node_ref_t node = (tb_xml_node_ref_t)tb_malloc0_type(tb_xml_cdata_t);
- tb_assert_and_check_return_val(node, tb_null);
-
- // init
- node->type = TB_XML_NODE_TYPE_CDATA;
- tb_string_init(&node->name);
- tb_string_init(&node->data);
- tb_string_cstrcpy(&node->name, "#cdata");
- if (cdata) tb_string_cstrcpy(&node->data, cdata);
-
- // ok
- return node;
-}
-tb_xml_node_ref_t tb_xml_node_init_comment(tb_char_t const* comment)
-{
- // make node
- tb_xml_node_ref_t node = (tb_xml_node_ref_t)tb_malloc0_type(tb_xml_comment_t);
- tb_assert_and_check_return_val(node, tb_null);
-
- // init
- node->type = TB_XML_NODE_TYPE_COMMENT;
- tb_string_init(&node->name);
- tb_string_init(&node->data);
- tb_string_cstrcpy(&node->name, "#comment");
- if (comment) tb_string_cstrcpy(&node->data, comment);
-
- // ok
- return node;
-}
-tb_xml_node_ref_t tb_xml_node_init_attribute(tb_char_t const* name, tb_char_t const* data)
-{
- // make node
- tb_xml_node_ref_t node = (tb_xml_node_ref_t)tb_malloc0_type(tb_xml_attribute_t);
- tb_assert_and_check_return_val(node, tb_null);
-
- // init
- node->type = TB_XML_NODE_TYPE_ATTRIBUTE;
- tb_string_init(&node->name);
- tb_string_init(&node->data);
- if (name) tb_string_cstrcpy(&node->name, name);
- if (data) tb_string_cstrcpy(&node->data, data);
-
- // ok
- return node;
-}
-tb_xml_node_ref_t tb_xml_node_init_document(tb_char_t const* version, tb_char_t const* charset)
-{
- // make node
- tb_xml_node_ref_t node = (tb_xml_node_ref_t)tb_malloc0_type(tb_xml_document_t);
- tb_assert_and_check_return_val(node, tb_null);
-
- // init
- node->type = TB_XML_NODE_TYPE_DOCUMENT;
- tb_string_init(&node->name);
- tb_string_init(&node->data);
- tb_string_init(&((tb_xml_document_t*)node)->version);
- tb_string_init(&((tb_xml_document_t*)node)->charset);
- tb_string_cstrcpy(&node->name, "#document");
- tb_string_cstrcpy(&((tb_xml_document_t*)node)->version, version? version : "2.0");
- tb_string_cstrcpy(&((tb_xml_document_t*)node)->charset, charset? charset : "utf-8");
-
- // ok
- return node;
-}
-tb_xml_node_ref_t tb_xml_node_init_document_type(tb_char_t const* type)
-{
- // make node
- tb_xml_node_ref_t node = (tb_xml_node_ref_t)tb_malloc0_type(tb_xml_document_type_t);
- tb_assert_and_check_return_val(node, tb_null);
-
- // init
- node->type = TB_XML_NODE_TYPE_DOCUMENT_TYPE;
- tb_string_init(&node->name);
- tb_string_init(&node->data);
- tb_string_init(&((tb_xml_document_type_t*)node)->type);
- tb_string_cstrcpy(&node->name, "#doctype");
- tb_string_cstrcpy(&((tb_xml_document_type_t*)node)->type, type? type : "");
-
- // ok
- return node;
-}
-tb_void_t tb_xml_node_exit(tb_xml_node_ref_t node)
-{
- if (node)
- {
- // free name & data
- tb_string_exit(&node->name);
- tb_string_exit(&node->data);
-
- // free version & charset for document
- if (node->type == TB_XML_NODE_TYPE_DOCUMENT)
- {
- tb_string_exit(&((tb_xml_document_t*)node)->version);
- tb_string_exit(&((tb_xml_document_t*)node)->charset);
- }
-
- // free type
- if (node->type == TB_XML_NODE_TYPE_DOCUMENT_TYPE)
- tb_string_exit(&((tb_xml_document_type_t*)node)->type);
-
- // free childs
- if (node->chead)
- {
- tb_xml_node_ref_t save = tb_null;
- tb_xml_node_ref_t next = node->chead;
- while (next)
- {
- // save
- save = next->next;
-
- // exit
- tb_xml_node_exit(next);
-
- // next
- next = save;
- }
- }
-
- // free attributes
- if (node->ahead)
- {
- tb_xml_node_ref_t save = tb_null;
- tb_xml_node_ref_t next = node->ahead;
- while (next)
- {
- // save
- save = next->next;
-
- // exit
- tb_xml_node_exit(next);
-
- // next
- next = save;
- }
- }
-
- // free it
- tb_free(node);
- }
-}
-tb_xml_node_ref_t tb_xml_node_chead(tb_xml_node_ref_t node)
-{
- // check
- tb_assert_and_check_return_val(node, tb_null);
-
- // get it
- return node->chead;
-}
-tb_size_t tb_xml_node_csize(tb_xml_node_ref_t node)
-{
- // check
- tb_assert_and_check_return_val(node, 0);
-
- // get it
- return node->csize;
-}
-tb_xml_node_ref_t tb_xml_node_ahead(tb_xml_node_ref_t node)
-{
- // check
- tb_assert_and_check_return_val(node, tb_null);
-
- // get it
- return node->ahead;
-}
-tb_size_t tb_xml_node_asize(tb_xml_node_ref_t node)
-{
- // check
- tb_assert_and_check_return_val(node, 0);
-
- // get it
- return node->asize;
-}
-tb_void_t tb_xml_node_insert_next(tb_xml_node_ref_t node, tb_xml_node_ref_t next)
-{
- // check
- tb_assert_and_check_return(node && next);
-
- // init
- next->parent = node->parent;
- next->next = node->next;
-
- // next
- node->next = next;
-}
-tb_void_t tb_xml_node_remove_next(tb_xml_node_ref_t node)
-{
- // check
- tb_assert_and_check_return(node);
-
- // next
- tb_xml_node_ref_t next = node->next;
-
- // save
- tb_xml_node_ref_t save = next? next->next : tb_null;
-
- // exit
- if (next) tb_xml_node_exit(next);
-
- // next
- node->next = save;
-}
-tb_void_t tb_xml_node_append_chead(tb_xml_node_ref_t node, tb_xml_node_ref_t child)
-{
- // check
- tb_assert_and_check_return(node && child);
-
- // init
- child->parent = node;
-
- // append
- if (node->chead)
- {
- child->next = node->chead;
- node->chead = child;
- node->csize++;
- }
- else
- {
- tb_assert(!node->ctail);
- node->ctail = node->chead = child;
- node->csize = 1;
- }
-}
-tb_void_t tb_xml_node_append_ctail(tb_xml_node_ref_t node, tb_xml_node_ref_t child)
-{
- // check
- tb_assert_and_check_return(node && child);
-
- // init
- child->parent = node;
- child->next = tb_null;
-
- // append
- if (node->ctail)
- {
- node->ctail->next = child;
- node->ctail = child;
- node->csize++;
- }
- else
- {
- tb_assert(!node->chead);
- node->ctail = node->chead = child;
- node->csize = 1;
- }
-}
-tb_void_t tb_xml_node_remove_chead(tb_xml_node_ref_t node)
-{
- // check
- tb_assert_and_check_return(node);
-
- // null?
- tb_check_return(node->chead);
-
- // remove
- if (node->chead != node->ctail)
- {
- // save
- tb_xml_node_ref_t save = node->chead;
-
- // remove
- node->chead = save->next;
-
- // exit
- tb_xml_node_exit(save);
-
- // size--
- node->csize--;
- }
- else
- {
- // save
- tb_xml_node_ref_t save = node->chead;
-
- // remove
- node->chead = tb_null;
- node->ctail = tb_null;
-
- // exit
- tb_xml_node_exit(save);
-
- // size--
- node->csize--;
- }
-}
-tb_void_t tb_xml_node_remove_ctail(tb_xml_node_ref_t node)
-{
- tb_trace_noimpl();
-}
-tb_void_t tb_xml_node_append_ahead(tb_xml_node_ref_t node, tb_xml_node_ref_t attribute)
-{
- // check
- tb_assert_and_check_return(node && attribute);
-
- // init
- attribute->parent = node;
-
- // append
- if (node->ahead)
- {
- attribute->next = node->ahead;
- node->ahead = attribute;
- node->asize++;
- }
- else
- {
- tb_assert(!node->atail);
- node->atail = node->ahead = attribute;
- node->asize = 1;
- }
-}
-tb_void_t tb_xml_node_append_atail(tb_xml_node_ref_t node, tb_xml_node_ref_t attribute)
-{
- // check
- tb_assert_and_check_return(node && attribute);
-
- // init
- attribute->parent = node;
- attribute->next = tb_null;
-
- // append
- if (node->atail)
- {
- node->atail->next = attribute;
- node->atail = attribute;
- node->asize++;
- }
- else
- {
- tb_assert(!node->ahead);
- node->atail = node->ahead = attribute;
- node->asize = 1;
- }
-}
-tb_xml_node_ref_t tb_xml_node_goto(tb_xml_node_ref_t node, tb_char_t const* path)
-{
- // check
- tb_assert_and_check_return_val(node && path, tb_null);
-
- // trace
- tb_trace_d("root: %s goto: %s", tb_string_cstr(&node->name), path);
-
- // skip '/'
- tb_char_t const* p = path; while (*p && *p == '/') p++;
-
- // is self?
- if (!*p) return node;
-
- // size
- tb_size_t n = tb_strlen(p);
-
- // walk the child nodes
- tb_xml_node_ref_t head = node->chead;
- for (node = head; node; node = node->next)
- {
- if (node->type == TB_XML_NODE_TYPE_ELEMENT)
- {
- // size
- tb_size_t m = tb_string_size(&node->name);
-
- // trace
- tb_trace_d("%s", tb_string_cstr(&node->name));
-
- // has it?
- if (!tb_string_cstrncmp(&node->name, p, m))
- {
- // is it?
- if (m == n) return node;
- else if (m < n)
- {
- // skip this node
- tb_char_t const* q = p + m;
-
- // is root?
- if (*q == '/')
- {
- // goto the child node
- tb_xml_node_ref_t c = tb_xml_node_goto(node, q);
- if (c) return c;
- }
- }
- }
- }
- }
-
- // no
- return tb_null;
-}
-
diff --git a/core/src/tbox/src/tbox/xml/node.h b/core/src/tbox/src/tbox/xml/node.h
deleted file mode 100644
index 26c5aeedf..000000000
--- a/core/src/tbox/src/tbox/xml/node.h
+++ /dev/null
@@ -1,333 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file node.h
- * @ingroup xml
- *
- */
-#ifndef TB_XML_NODE_H
-#define TB_XML_NODE_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/*! the xml node type
- *
- * @note see http://www.w3.org/TR/REC-DOM-Level-1/
- *
- */
-typedef enum __tb_xml_node_type_t
-{
- TB_XML_NODE_TYPE_NONE = 0
-, TB_XML_NODE_TYPE_ELEMENT = 1
-, TB_XML_NODE_TYPE_ATTRIBUTE = 2
-, TB_XML_NODE_TYPE_TEXT = 3
-, TB_XML_NODE_TYPE_CDATA = 4
-, TB_XML_NODE_TYPE_ENTITY_REFERENCE = 5
-, TB_XML_NODE_TYPE_ENTITY = 6
-, TB_XML_NODE_TYPE_PROCESSING_INSTRUCTION = 7
-, TB_XML_NODE_TYPE_COMMENT = 8
-, TB_XML_NODE_TYPE_DOCUMENT = 9
-, TB_XML_NODE_TYPE_DOCUMENT_TYPE = 10
-, TB_XML_NODE_TYPE_DOCUMENT_FRAGMENT = 11
-, TB_XML_NODE_TYPE_NOTATION = 12
-
-}tb_xml_node_type_t;
-
-/// the xml node
-typedef struct __tb_xml_node_t
-{
- /// the node type
- tb_size_t type;
-
- /// the node name
- tb_string_t name;
-
- /// the node data
- tb_string_t data;
-
- /// the next
- struct __tb_xml_node_t* next;
-
- /// the childs head
- struct __tb_xml_node_t* chead;
-
- /// the childs tail
- struct __tb_xml_node_t* ctail;
-
- /// the childs size
- tb_size_t csize;
-
- /// the attributes head
- struct __tb_xml_node_t* ahead;
-
- /// the attributes tail
- struct __tb_xml_node_t* atail;
-
- /// the attributes size
- tb_size_t asize;
-
- /// the parent
- struct __tb_xml_node_t* parent;
-
-}tb_xml_node_t;
-
-/// the xml element type
-typedef struct __tb_xml_element_t
-{
- /// the node base
- tb_xml_node_t base;
-
-}tb_xml_element_t;
-
-/// the xml text type
-typedef struct __tb_xml_text_t
-{
- /// the node base
- tb_xml_node_t base;
-
-}tb_xml_text_t;
-
-/// the xml cdata type
-typedef struct __tb_xml_cdata_t
-{
- /// the node base
- tb_xml_node_t base;
-
-}tb_xml_cdata_t;
-
-/// the xml comment type
-typedef struct __tb_xml_comment_t
-{
- /// the node base
- tb_xml_node_t base;
-
-}tb_xml_comment_t;
-
-/*! the xml attribute type
- *
- * <pre>
- * inherit node,
- * but since they are not actually child nodes of the element they describe,
- * the DOM does not consider them part of the document tree.
- * </pre>
- */
-typedef struct __tb_xml_attribute_t
-{
- /// the node base
- tb_xml_node_t base;
-
-}tb_xml_attribute_t;
-
-/// the xml document type
-typedef struct __tb_xml_document_t
-{
- /// the node base
- tb_xml_node_t base;
-
- /// the version
- tb_string_t version;
-
- /// the charset
- tb_string_t charset;
-
-}tb_xml_document_t;
-
-/// the xml document type type
-typedef struct __tb_xml_document_type_t
-{
- /// the node base
- tb_xml_node_t base;
-
- /// the type
- tb_string_t type;
-
-}tb_xml_document_type_t;
-
-/// the xml node ref type
-typedef tb_xml_node_t* tb_xml_node_ref_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init element node
- *
- * @param name the element name
- * @return the element node
- */
-tb_xml_node_ref_t tb_xml_node_init_element(tb_char_t const* name);
-
-/*! init text node
- *
- * @param data the element text
- * @return the element node
- */
-tb_xml_node_ref_t tb_xml_node_init_text(tb_char_t const* data);
-
-/*! init cdata node
- *
- * @param cdata the element cdata
- * @return the element node
- */
-tb_xml_node_ref_t tb_xml_node_init_cdata(tb_char_t const* cdata);
-
-/*! init comment node
- *
- * @param comment the element comment
- * @return the element node
- */
-tb_xml_node_ref_t tb_xml_node_init_comment(tb_char_t const* comment);
-
-/*! init attribute node
- *
- * @param name the attribute name
- * @param data the attribute data
- * @return the element node
- */
-tb_xml_node_ref_t tb_xml_node_init_attribute(tb_char_t const* name, tb_char_t const* data);
-
-/*! init document node
- *
- * @param version the xml version
- * @param encoding the xml encoding
- * @return the element node
- */
-tb_xml_node_ref_t tb_xml_node_init_document(tb_char_t const* version, tb_char_t const* encoding);
-
-/*! init document type node
- *
- * @param type the document type
- * @return the element node
- */
-tb_xml_node_ref_t tb_xml_node_init_document_type(tb_char_t const* type);
-
-/*! exit the xml node
- *
- * @param node the element node
- */
-tb_void_t tb_xml_node_exit(tb_xml_node_ref_t node);
-
-/*! goto node by the gived path
- *
- * @param node the root node
- * @return the goto node
- */
-tb_xml_node_ref_t tb_xml_node_goto(tb_xml_node_ref_t node, tb_char_t const* path);
-
-/*! the xml childs head node
- *
- * @param node the xml node
- * @return the xml childs head node
- */
-tb_xml_node_ref_t tb_xml_node_chead(tb_xml_node_ref_t node);
-
-/*! the xml childs count
- *
- * @param node the xml node
- * @return the xml childs count
- */
-tb_size_t tb_xml_node_csize(tb_xml_node_ref_t node);
-
-/*! the xml attributes head node
- *
- * @param node the xml node
- * @return the xml attributes head node
- */
-tb_xml_node_ref_t tb_xml_node_ahead(tb_xml_node_ref_t node);
-
-/*! the xml attributes count
- *
- * @param node the xml node
- * @return the xml attributes count
- */
-tb_size_t tb_xml_node_asize(tb_xml_node_ref_t node);
-
-/*! insert to the next node
- *
- * @param node the xml node
- * @param next the xml next node
- */
-tb_void_t tb_xml_node_insert_next(tb_xml_node_ref_t node, tb_xml_node_ref_t next);
-
-/*! remove the next node
- *
- * @param node the xml node
- */
-tb_void_t tb_xml_node_remove_next(tb_xml_node_ref_t node);
-
-/*! append the node to the childs head
- *
- * @param node the xml node
- * @param child the xml child node
- */
-tb_void_t tb_xml_node_append_chead(tb_xml_node_ref_t node, tb_xml_node_ref_t child);
-
-/*! append the node to the childs tail
- *
- * @param node the xml node
- * @param child the xml child node
- */
-tb_void_t tb_xml_node_append_ctail(tb_xml_node_ref_t node, tb_xml_node_ref_t child);
-
-/*! remove the node from the childs head
- *
- * @param node the xml node
- */
-tb_void_t tb_xml_node_remove_chead(tb_xml_node_ref_t node);
-
-/*! remove the node from the childs tail
- *
- * @param node the xml node
- */
-tb_void_t tb_xml_node_remove_ctail(tb_xml_node_ref_t node);
-
-/*! append the node to the attributes head
- *
- * @param node the xml node
- * @param attribute the xml attribute node
- */
-tb_void_t tb_xml_node_append_ahead(tb_xml_node_ref_t node, tb_xml_node_ref_t attribute);
-
-/*! append the node to the attributes tail
- *
- * @param node the xml node
- * @param attribute the xml attribute node
- */
-tb_void_t tb_xml_node_append_atail(tb_xml_node_ref_t node, tb_xml_node_ref_t attribute);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/xml/prefix.h b/core/src/tbox/src/tbox/xml/prefix.h
deleted file mode 100644
index 471c79aaf..000000000
--- a/core/src/tbox/src/tbox/xml/prefix.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file prefix.h
- *
- */
-#ifndef TB_XML_PREFIX_H
-#define TB_XML_PREFIX_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "../prefix.h"
-#include "../libc/libc.h"
-#include "../utils/utils.h"
-#include "../stream/stream.h"
-#include "../string/string.h"
-#include "../memory/memory.h"
-#include "../platform/platform.h"
-#include "../container/container.h"
-
-
-#endif
diff --git a/core/src/tbox/src/tbox/xml/reader.c b/core/src/tbox/src/tbox/xml/reader.c
deleted file mode 100644
index 370e52fc5..000000000
--- a/core/src/tbox/src/tbox/xml/reader.c
+++ /dev/null
@@ -1,928 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file reader.c
- * @ingroup xml
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "xml"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "reader.h"
-#include "../charset/charset.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-
-#ifdef __tb_small__
-# define TB_XML_READER_ATTRIBUTES_MAXN (64)
-#else
-# define TB_XML_READER_ATTRIBUTES_MAXN (128)
-#endif
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the xml reader impl type
-typedef struct __tb_xml_reader_impl_t
-{
- // the event
- tb_size_t event;
-
- // the level
- tb_size_t level;
-
- // is bowner of the input stream?
- tb_bool_t bowner;
-
- // the input stream
- tb_stream_ref_t istream;
-
- // the filter stream
- tb_stream_ref_t fstream;
-
- // the reader stream
- tb_stream_ref_t rstream;
-
- // the version
- tb_string_t version;
-
- // the charset
- tb_string_t charset;
-
- // the element
- tb_string_t element;
-
- // the element name
- tb_string_t element_name;
-
- // the text
- tb_string_t text;
-
- // the attribute name
- tb_string_t attribute_name;
-
- // the attribute data
- tb_string_t attribute_data;
-
- // the attributes
- tb_xml_attribute_t attributes[TB_XML_READER_ATTRIBUTES_MAXN];
-
-}tb_xml_reader_impl_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * parser implementation
- */
-static tb_char_t const* tb_xml_reader_element_parse(tb_xml_reader_impl_t* reader)
-{
- // clear element
- tb_string_clear(&reader->element);
-
- // parse element
- tb_char_t ch = '\0';
- tb_size_t in = 0;
- while (tb_stream_bread_s8(reader->rstream, (tb_sint8_t*)&ch))
- {
- // append element
- if (!in && ch == '<') in = 1;
- else if (in)
- {
- if (ch != '>') tb_string_chrcat(&reader->element, ch);
- else return tb_string_cstr(&reader->element);
- }
- }
-
- // failed
- tb_assertf(0, "invalid element: %s from %s", tb_string_cstr(&reader->element), tb_url_cstr(tb_stream_url(reader->istream)));
- return tb_null;
-}
-static tb_char_t const* tb_xml_reader_text_parse(tb_xml_reader_impl_t* reader)
-{
- // clear text
- tb_string_clear(&reader->text);
-
- // parse text
- tb_char_t* pc = tb_null;
- while (tb_stream_need(reader->rstream, (tb_byte_t**)&pc, 1) && pc)
- {
- // is end? </ ..>
- if (pc[0] == '<') return tb_string_cstr(&reader->text);
- else
- {
- tb_string_chrcat(&reader->text, *pc);
- if (!tb_stream_skip(reader->rstream, 1)) return tb_null;
- }
- }
- return tb_null;
-}
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_xml_reader_ref_t tb_xml_reader_init()
-{
- // init reader
- tb_xml_reader_impl_t* reader = tb_malloc0_type(tb_xml_reader_impl_t);
- tb_assert_and_check_return_val(reader, tb_null);
-
- // init string
- tb_string_init(&reader->text);
- tb_string_init(&reader->version);
- tb_string_init(&reader->charset);
- tb_string_init(&reader->element);
- tb_string_init(&reader->element_name);
- tb_string_init(&reader->attribute_name);
- tb_string_init(&reader->attribute_data);
- tb_string_cstrcpy(&reader->version, "2.0");
- tb_string_cstrcpy(&reader->charset, "utf-8");
-
- // init attributes
- tb_size_t i = 0;
- for (i = 0; i < TB_XML_READER_ATTRIBUTES_MAXN; i++)
- {
- tb_xml_node_ref_t node = (tb_xml_node_ref_t)(reader->attributes + i);
- tb_string_init(&node->name);
- tb_string_init(&node->data);
- }
-
- // ok
- return (tb_xml_reader_ref_t)reader;
-}
-tb_void_t tb_xml_reader_exit(tb_xml_reader_ref_t reader)
-{
- // check
- tb_xml_reader_impl_t* impl = (tb_xml_reader_impl_t*)reader;
- tb_assert_and_check_return(impl);
-
- // clos it first
- tb_xml_reader_clos(reader);
-
- // exit the filter stream
- if (impl->fstream) tb_stream_exit(impl->fstream);
-
- // exit text
- tb_string_exit(&impl->text);
-
- // exit version
- tb_string_exit(&impl->version);
-
- // exit charset
- tb_string_exit(&impl->charset);
-
- // exit element
- tb_string_exit(&impl->element);
-
- // exit element name
- tb_string_exit(&impl->element_name);
-
- // exit attribute name
- tb_string_exit(&impl->attribute_name);
-
- // exit attribute data
- tb_string_exit(&impl->attribute_data);
-
- // exit attributes
- tb_long_t i = 0;
- for (i = 0; i < TB_XML_READER_ATTRIBUTES_MAXN; i++)
- {
- tb_xml_node_ref_t node = (tb_xml_node_ref_t)(impl->attributes + i);
- tb_string_exit(&node->name);
- tb_string_exit(&node->data);
- }
-
- // free it
- tb_free(impl);
-}
-tb_bool_t tb_xml_reader_open(tb_xml_reader_ref_t reader, tb_stream_ref_t stream, tb_bool_t bowner)
-{
- // check
- tb_xml_reader_impl_t* impl = (tb_xml_reader_impl_t*)reader;
- tb_assert_and_check_return_val(impl && stream, tb_false);
-
- // done
- tb_bool_t ok = tb_false;
- do
- {
- // check
- tb_assert_and_check_break(!impl->rstream && !impl->istream);
-
- // init level
- impl->level = 0;
-
- // init owner
- impl->bowner = bowner;
-
- // init the input stream
- impl->istream = stream;
-
- // init the reader stream
- impl->rstream = stream;
-
- // open the reader stream if be not opened
- if (!tb_stream_is_opened(impl->rstream) && !tb_stream_open(impl->rstream)) break;
-
- // clear text
- tb_string_clear(&impl->text);
-
- // clear element
- tb_string_clear(&impl->element);
-
- // clear name
- tb_string_clear(&impl->element_name);
-
- // clear attribute name
- tb_string_clear(&impl->attribute_name);
-
- // clear attribute data
- tb_string_clear(&impl->attribute_data);
-
- // clear attributes
- tb_long_t i = 0;
- for (i = 0; i < TB_XML_READER_ATTRIBUTES_MAXN; i++)
- {
- tb_xml_node_ref_t node = (tb_xml_node_ref_t)(impl->attributes + i);
- tb_string_clear(&node->name);
- tb_string_clear(&node->data);
- }
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed? close it
- if (!ok) tb_xml_reader_clos(reader);
-
- // ok?
- return ok;
-}
-tb_void_t tb_xml_reader_clos(tb_xml_reader_ref_t reader)
-{
- // check
- tb_xml_reader_impl_t* impl = (tb_xml_reader_impl_t*)reader;
- tb_assert_and_check_return(impl);
-
- // clos the reader stream
- if (impl->rstream) tb_stream_clos(impl->rstream);
- impl->rstream = tb_null;
-
- // exit the input stream
- if (impl->istream && impl->bowner) tb_stream_exit(impl->istream);
- impl->istream = tb_null;
-
- // clear level
- impl->level = 0;
-
- // clear owner
- impl->bowner = tb_false;
-
- // clear text
- tb_string_clear(&impl->text);
-
- // clear element
- tb_string_clear(&impl->element);
-
- // clear name
- tb_string_clear(&impl->element_name);
-
- // clear attribute name
- tb_string_clear(&impl->attribute_name);
-
- // clear attribute data
- tb_string_clear(&impl->attribute_data);
-
- // clear attributes
- tb_long_t i = 0;
- for (i = 0; i < TB_XML_READER_ATTRIBUTES_MAXN; i++)
- {
- tb_xml_node_ref_t node = (tb_xml_node_ref_t)(impl->attributes + i);
- tb_string_clear(&node->name);
- tb_string_clear(&node->data);
- }
-}
-tb_stream_ref_t tb_xml_reader_stream(tb_xml_reader_ref_t reader)
-{
- // check
- tb_xml_reader_impl_t* impl = (tb_xml_reader_impl_t*)reader;
- tb_assert_and_check_return_val(impl, tb_null);
-
- return impl->rstream;
-}
-tb_size_t tb_xml_reader_level(tb_xml_reader_ref_t reader)
-{
- // check
- tb_xml_reader_impl_t* impl = (tb_xml_reader_impl_t*)reader;
- tb_assert_and_check_return_val(impl, 0);
-
- return impl->level;
-}
-tb_size_t tb_xml_reader_next(tb_xml_reader_ref_t reader)
-{
- // check
- tb_xml_reader_impl_t* impl = (tb_xml_reader_impl_t*)reader;
- tb_assert_and_check_return_val(impl && impl->rstream, TB_XML_READER_EVENT_NONE);
-
- // reset event
- impl->event = TB_XML_READER_EVENT_NONE;
-
- // next
- while (!impl->event)
- {
- // peek character
- tb_char_t* pc = tb_null;
- if (!tb_stream_need(impl->rstream, (tb_byte_t**)&pc, 1) || !pc) break;
-
- // is element?
- if (*pc == '<')
- {
- // parse element: <...>
- tb_char_t const* element = tb_xml_reader_element_parse(impl);
- tb_assert_and_check_break(element);
-
- // is document begin: <?xml version="..." charset=".." ?>
- tb_size_t size = tb_string_size(&impl->element);
- if (size > 4 && !tb_strnicmp(element, "?xml", 4))
- {
- // update event
- impl->event = TB_XML_READER_EVENT_DOCUMENT;
-
- // update version & charset
- tb_xml_node_ref_t attr = (tb_xml_node_ref_t)tb_xml_reader_attributes(reader);
- for (; attr; attr = attr->next)
- {
- if (!tb_string_cstricmp(&attr->name, "version")) tb_string_strcpy(&impl->version, &attr->data);
- if (!tb_string_cstricmp(&attr->name, "encoding")) tb_string_strcpy(&impl->charset, &attr->data);
- }
-
- // transform stream => utf-8
- if (tb_string_cstricmp(&impl->charset, "utf-8") && tb_string_cstricmp(&impl->charset, "utf8"))
- {
- // charset
- tb_size_t charset = TB_CHARSET_TYPE_UTF8;
- if (!tb_string_cstricmp(&impl->charset, "gb2312") || !tb_string_cstricmp(&impl->charset, "gbk"))
- charset = TB_CHARSET_TYPE_GB2312;
- else tb_trace_e("the charset: %s is not supported", tb_string_cstr(&impl->charset));
-
- // init transform stream
- if (charset != TB_CHARSET_TYPE_UTF8)
- {
-#ifdef TB_CONFIG_MODULE_HAVE_CHARSET
- // init the filter stream
- if (!impl->fstream) impl->fstream = tb_stream_init_filter_from_charset(impl->istream, charset, TB_CHARSET_TYPE_UTF8);
- else
- {
- // ctrl stream
- if (!tb_stream_ctrl(impl->fstream, TB_STREAM_CTRL_FLTR_SET_STREAM, impl->istream)) break;
-
- // the filter
- tb_filter_ref_t filter = tb_null;
- if (!tb_stream_ctrl(impl->fstream, TB_STREAM_CTRL_FLTR_GET_FILTER, &filter)) break;
- tb_assert_and_check_break(filter);
-
- // ctrl filter
- if (!tb_filter_ctrl(filter, TB_FILTER_CTRL_CHARSET_SET_FTYPE, charset)) break;
- }
-
- // open the filter stream
- if (impl->fstream && tb_stream_open(impl->fstream))
- impl->rstream = impl->fstream;
- tb_string_cstrcpy(&impl->charset, "utf-8");
-#else
- // trace
- tb_trace_e("unicode type is not supported, please enable charset module config if you want to use it!");
-#endif
- }
- }
- }
- // is document type: <!DOCTYPE ... >
- else if (size > 8 && !tb_strnicmp(element, "!DOCTYPE", 8))
- {
- // update event
- impl->event = TB_XML_READER_EVENT_DOCUMENT_TYPE;
- }
- // is element end: </name>
- else if (size > 1 && element[0] == '/')
- {
- // check
- tb_check_break(impl->level);
-
- // update event
- impl->event = TB_XML_READER_EVENT_ELEMENT_END;
-
- // leave
- impl->level--;
- }
- // is comment: <!-- text -->
- else if (size >= 3 && !tb_strncmp(element, "!--", 3))
- {
- // no comment end?
- if (element[size - 2] != '-' || element[size - 1] != '-')
- {
- // patch '>'
- tb_string_chrcat(&impl->element, '>');
-
- // seek to comment end
- tb_char_t ch = '\0';
- tb_int_t n = 0;
- while (tb_stream_bread_s8(impl->rstream, (tb_sint8_t*)&ch))
- {
- // -->
- if (n == 2 && ch == '>') break;
- else
- {
- // append it
- tb_string_chrcat(&impl->element, ch);
-
- if (ch == '-') n++;
- else n = 0;
- }
- }
-
- // update event
- if (ch != '\0') impl->event = TB_XML_READER_EVENT_COMMENT;
- }
- else impl->event = TB_XML_READER_EVENT_COMMENT;
- }
- // is cdata: <![CDATA[ text ]]>
- else if (size >= 8 && !tb_strnicmp(element, "![CDATA[", 8))
- {
- if (element[size - 2] != ']' || element[size - 1] != ']')
- {
- // patch '>'
- tb_string_chrcat(&impl->element, '>');
-
- // seek to cdata end
- tb_char_t ch = '\0';
- tb_int_t n = 0;
- while (tb_stream_bread_s8(impl->rstream, (tb_sint8_t*)&ch))
- {
- // ]]>
- if (n == 2 && ch == '>') break;
- else
- {
- // append it
- tb_string_chrcat(&impl->element, ch);
-
- if (ch == ']') n++;
- else n = 0;
- }
- }
-
- // update event
- if (ch != '\0') impl->event = TB_XML_READER_EVENT_CDATA;
- }
- else impl->event = TB_XML_READER_EVENT_CDATA;
- }
- // is empty element: <name/>
- else if (size > 1 && element[size - 1] == '/')
- {
- // update event
- impl->event = TB_XML_READER_EVENT_ELEMENT_EMPTY;
- }
- // is element begin: <name>
- else
- {
- // update event
- impl->event = TB_XML_READER_EVENT_ELEMENT_BEG;
-
- // enter
- impl->level++;
- }
-
- // trace
-// tb_trace_d("<%s>", element);
- }
- // is text: <> text </>
- else if (*pc)
- {
- // parse text: <> ... <>
- tb_char_t const* text = tb_xml_reader_text_parse(impl);
- if (text && tb_string_cstrcmp(&impl->text, "\r\n") && tb_string_cstrcmp(&impl->text, "\n"))
- impl->event = TB_XML_READER_EVENT_TEXT;
-
- // trace
-// tb_trace_d("%s", text);
- }
- else
- {
- // skip the invalid character
- if (!tb_stream_skip(impl->rstream, 1)) break;
- }
- }
-
- // ok?
- return impl->event;
-}
-tb_bool_t tb_xml_reader_goto(tb_xml_reader_ref_t reader, tb_char_t const* path)
-{
- // check
- tb_xml_reader_impl_t* impl = (tb_xml_reader_impl_t*)reader;
- tb_assert_and_check_return_val(impl && impl->rstream && path, tb_false);
-
- // trace
- tb_trace_d("goto: %s", path);
-
- // init level
- impl->level = 0;
-
- // seek to the stream head
- if (!tb_stream_seek(impl->rstream, 0)) return tb_false;
-
- // init
- tb_static_string_t s;
- tb_char_t data[8192];
- if (!tb_static_string_init(&s, data, 8192)) return tb_false;
-
- // save the current offset
- tb_hize_t save = tb_stream_offset(impl->rstream);
-
- // done
- tb_bool_t ok = tb_false;
- tb_bool_t leave = tb_false;
- tb_size_t event = TB_XML_READER_EVENT_NONE;
- while (!leave && !ok && (event = tb_xml_reader_next(reader)))
- {
- switch (event)
- {
- case TB_XML_READER_EVENT_ELEMENT_EMPTY:
- {
- // name
- tb_char_t const* name = tb_xml_reader_element(reader);
- tb_assert_and_check_break_state(name, leave, tb_true);
-
- // append
- tb_size_t n = tb_static_string_size(&s);
- tb_static_string_chrcat(&s, '/');
- tb_static_string_cstrcat(&s, name);
-
- // ok?
- if (!tb_static_string_cstricmp(&s, path)) ok = tb_true;
-
- // trace
- tb_trace_d("path: %s", tb_static_string_cstr(&s));
-
- // remove
- tb_static_string_strip(&s, n);
-
- // restore
- if (ok) if (!(ok = tb_stream_seek(impl->rstream, save))) leave = tb_true;
- }
- break;
- case TB_XML_READER_EVENT_ELEMENT_BEG:
- {
- // name
- tb_char_t const* name = tb_xml_reader_element(reader);
- tb_assert_and_check_break_state(name, leave, tb_true);
-
- // append
- tb_static_string_chrcat(&s, '/');
- tb_static_string_cstrcat(&s, name);
-
- // ok?
- if (!tb_static_string_cstricmp(&s, path)) ok = tb_true;
-
- // trace
- tb_trace_d("path: %s", tb_static_string_cstr(&s));
-
- // restore
- if (ok) if (!(ok = tb_stream_seek(impl->rstream, save))) leave = tb_true;
- }
- break;
- case TB_XML_READER_EVENT_ELEMENT_END:
- {
- // remove
- tb_long_t p = tb_static_string_strrchr(&s, 0, '/');
- if (p >= 0) tb_static_string_strip(&s, p);
-
- // ok?
- if (!tb_static_string_cstricmp(&s, path)) ok = tb_true;
-
- // trace
- tb_trace_d("path: %s", tb_static_string_cstr(&s));
-
- // restore
- if (ok) if (!(ok = tb_stream_seek(impl->rstream, save))) leave = tb_true;
- }
- break;
- default:
- break;
- }
-
- // save
- save = tb_stream_offset(impl->rstream);
- }
-
- // exit string
- tb_static_string_exit(&s);
-
- // clear level
- impl->level = 0;
-
- // failed? restore to the stream head
- if (!ok) tb_stream_seek(impl->rstream, 0);
-
- // ok?
- return ok;
-}
-tb_xml_node_ref_t tb_xml_reader_load(tb_xml_reader_ref_t reader)
-{
- // check
- tb_assert_and_check_return_val(reader, tb_null);
-
- // done
- tb_bool_t ok = tb_true;
- tb_xml_node_ref_t node = tb_null;
- tb_size_t event = TB_XML_READER_EVENT_NONE;
- while (ok && (event = tb_xml_reader_next(reader)))
- {
- // init document node
- if (!node)
- {
- node = tb_xml_node_init_document(tb_xml_reader_version(reader), tb_xml_reader_charset(reader));
- tb_assert_and_check_break_state(node && !node->parent, ok, tb_false);
- }
-
- switch (event)
- {
- case TB_XML_READER_EVENT_DOCUMENT:
- break;
- case TB_XML_READER_EVENT_DOCUMENT_TYPE:
- {
- // init
- tb_xml_node_ref_t doctype = tb_xml_node_init_document_type(tb_xml_reader_doctype(reader));
- tb_assert_and_check_break_state(doctype, ok, tb_false);
-
- // append
- tb_xml_node_append_ctail(node, doctype);
- tb_assert_and_check_break_state(doctype->parent, ok, tb_false);
- }
- break;
- case TB_XML_READER_EVENT_ELEMENT_EMPTY:
- {
- // init
- tb_xml_node_ref_t element = tb_xml_node_init_element(tb_xml_reader_element(reader));
- tb_assert_and_check_break_state(element, ok, tb_false);
-
- // attributes
- tb_xml_node_ref_t attr = tb_xml_reader_attributes(reader);
- for (; attr; attr = attr->next)
- tb_xml_node_append_atail(element, tb_xml_node_init_attribute(tb_string_cstr(&attr->name), tb_string_cstr(&attr->data)));
-
- // append
- tb_xml_node_append_ctail(node, element);
- tb_assert_and_check_break_state(element->parent, ok, tb_false);
- }
- break;
- case TB_XML_READER_EVENT_ELEMENT_BEG:
- {
- // init
- tb_xml_node_ref_t element = tb_xml_node_init_element(tb_xml_reader_element(reader));
- tb_assert_and_check_break_state(element, ok, tb_false);
-
- // attributes
- tb_xml_node_ref_t attr = tb_xml_reader_attributes(reader);
- for (; attr; attr = attr->next)
- tb_xml_node_append_atail(element, tb_xml_node_init_attribute(tb_string_cstr(&attr->name), tb_string_cstr(&attr->data)));
-
- // append
- tb_xml_node_append_ctail(node, element);
- tb_assert_and_check_break_state(element->parent, ok, tb_false);
-
- // enter
- node = element;
- }
- break;
- case TB_XML_READER_EVENT_ELEMENT_END:
- {
- // check
- tb_assert_and_check_break_state(node, ok, tb_false);
-
- // the parent node
- node = node->parent;
- }
- break;
- case TB_XML_READER_EVENT_TEXT:
- {
- // init
- tb_xml_node_ref_t text = tb_xml_node_init_text(tb_xml_reader_text(reader));
- tb_assert_and_check_break_state(text, ok, tb_false);
-
- // append
- tb_xml_node_append_ctail(node, text);
- tb_assert_and_check_break_state(text->parent, ok, tb_false);
- }
- break;
- case TB_XML_READER_EVENT_CDATA:
- {
- // init
- tb_xml_node_ref_t cdata = tb_xml_node_init_cdata(tb_xml_reader_cdata(reader));
- tb_assert_and_check_break_state(cdata, ok, tb_false);
-
- // append
- tb_xml_node_append_ctail(node, cdata);
- tb_assert_and_check_break_state(cdata->parent, ok, tb_false);
-
- }
- break;
- case TB_XML_READER_EVENT_COMMENT:
- {
- // init
- tb_xml_node_ref_t comment = tb_xml_node_init_comment(tb_xml_reader_comment(reader));
- tb_assert_and_check_break_state(comment, ok, tb_false);
-
- // append
- tb_xml_node_append_ctail(node, comment);
- tb_assert_and_check_break_state(comment->parent, ok, tb_false);
- }
- break;
- default:
- break;
- }
- }
-
- // failed?
- if (!ok)
- {
- // exit it
- if (node) tb_xml_node_exit(node);
- node = tb_null;
- }
-
- // ok
- return node;
-}
-tb_char_t const* tb_xml_reader_version(tb_xml_reader_ref_t reader)
-{
- // check
- tb_xml_reader_impl_t* impl = (tb_xml_reader_impl_t*)reader;
- tb_assert_and_check_return_val(impl, tb_null);
-
- // text
- return tb_string_cstr(&impl->version);
-}
-tb_char_t const* tb_xml_reader_charset(tb_xml_reader_ref_t reader)
-{
- // check
- tb_xml_reader_impl_t* impl = (tb_xml_reader_impl_t*)reader;
- tb_assert_and_check_return_val(impl, tb_null);
-
- // text
- return tb_string_cstr(&impl->charset);
-}
-tb_char_t const* tb_xml_reader_comment(tb_xml_reader_ref_t reader)
-{
- // check
- tb_xml_reader_impl_t* impl = (tb_xml_reader_impl_t*)reader;
- tb_assert_and_check_return_val(impl && impl->event == TB_XML_READER_EVENT_COMMENT, tb_null);
-
- // init
- tb_char_t const* p = tb_string_cstr(&impl->element);
- tb_size_t n = tb_string_size(&impl->element);
- tb_assert_and_check_return_val(p && n >= 6, tb_null);
-
- // comment
- tb_string_cstrncpy(&impl->text, p + 3, n - 5);
- return tb_string_cstr(&impl->text);
-}
-tb_char_t const* tb_xml_reader_cdata(tb_xml_reader_ref_t reader)
-{
- // check
- tb_xml_reader_impl_t* impl = (tb_xml_reader_impl_t*)reader;
- tb_assert_and_check_return_val(impl && impl->event == TB_XML_READER_EVENT_CDATA, tb_null);
-
- // init
- tb_char_t const* p = tb_string_cstr(&impl->element);
- tb_size_t n = tb_string_size(&impl->element);
- tb_assert_and_check_return_val(p && n >= 11, tb_null);
-
- // comment
- tb_string_cstrncpy(&impl->text, p + 8, n - 10);
- return tb_string_cstr(&impl->text);
-}
-tb_char_t const* tb_xml_reader_text(tb_xml_reader_ref_t reader)
-{
- // check
- tb_xml_reader_impl_t* impl = (tb_xml_reader_impl_t*)reader;
- tb_assert_and_check_return_val(impl && impl->event == TB_XML_READER_EVENT_TEXT, tb_null);
-
- // text
- return tb_string_cstr(&impl->text);
-}
-tb_char_t const* tb_xml_reader_element(tb_xml_reader_ref_t reader)
-{
- // check
- tb_xml_reader_impl_t* impl = (tb_xml_reader_impl_t*)reader;
- tb_assert_and_check_return_val(impl && ( impl->event == TB_XML_READER_EVENT_ELEMENT_BEG
- || impl->event == TB_XML_READER_EVENT_ELEMENT_END
- || impl->event == TB_XML_READER_EVENT_ELEMENT_EMPTY), tb_null);
-
- // init
- tb_char_t const* p = tb_null;
- tb_char_t const* b = tb_string_cstr(&impl->element);
- tb_char_t const* e = b + tb_string_size(&impl->element);
- tb_assert_and_check_return_val(b, tb_null);
-
- // </name> or <name ... />
- if (b < e && *b == '/') b++;
- for (p = b; p < e && *p && !tb_isspace(*p) && *p != '/'; p++) ;
-
- // ok?
- return p > b? tb_string_cstrncpy(&impl->element_name, b, p - b) : tb_null;
-}
-tb_char_t const* tb_xml_reader_doctype(tb_xml_reader_ref_t reader)
-{
- // check
- tb_xml_reader_impl_t* impl = (tb_xml_reader_impl_t*)reader;
- tb_assert_and_check_return_val(impl && impl->event == TB_XML_READER_EVENT_DOCUMENT_TYPE, tb_null);
-
- // doctype
- tb_char_t const* p = tb_string_cstr(&impl->element);
- tb_assert_and_check_return_val(p, tb_null);
-
- // skip !DOCTYPE
- return (p + 9);
-}
-tb_xml_node_ref_t tb_xml_reader_attributes(tb_xml_reader_ref_t reader)
-{
- // check
- tb_xml_reader_impl_t* impl = (tb_xml_reader_impl_t*)reader;
- tb_assert_and_check_return_val(impl && ( impl->event == TB_XML_READER_EVENT_DOCUMENT
- || impl->event == TB_XML_READER_EVENT_ELEMENT_BEG
- || impl->event == TB_XML_READER_EVENT_ELEMENT_END
- || impl->event == TB_XML_READER_EVENT_ELEMENT_EMPTY), tb_null);
-
- // init
- tb_char_t const* p = tb_string_cstr(&impl->element);
- tb_char_t const* e = p + tb_string_size(&impl->element);
-
- // skip name
- while (p < e && *p && !tb_isspace(*p)) p++;
- while (p < e && *p && tb_isspace(*p)) p++;
-
- // parse attributes
- tb_size_t n = 0;
- while (p < e)
- {
- // parse name
- tb_string_clear(&impl->attribute_name);
- for (; p < e && *p != '='; p++) if (!tb_isspace(*p)) tb_string_chrcat(&impl->attribute_name, *p);
- if (*p != '=') break;
-
- // parse data
- tb_string_clear(&impl->attribute_data);
- for (p++; p < e && (*p != '\'' && *p != '\"'); p++) ;
- if (*p != '\'' && *p != '\"') break;
- for (p++; p < e && (*p != '\'' && *p != '\"'); p++) tb_string_chrcat(&impl->attribute_data, *p);
- if (*p != '\'' && *p != '\"') break;
- p++;
-
- // append node
- if (tb_string_cstr(&impl->attribute_name) && tb_string_cstr(&impl->attribute_data))
- {
- // node
- tb_xml_node_ref_t prev = n > 0? (tb_xml_node_ref_t)&impl->attributes[n - 1] : tb_null;
- tb_xml_node_ref_t node = (tb_xml_node_ref_t)&impl->attributes[n];
-
- // init node
- tb_string_strcpy(&node->name, &impl->attribute_name);
- tb_string_strcpy(&node->data, &impl->attribute_data);
-
- // append node
- if (prev) prev->next = node;
- node->next = tb_null;
-
- // next
- n++;
- }
- }
-
- // ok?
- return n? (tb_xml_node_ref_t)&impl->attributes[0] : tb_null;
-}
diff --git a/core/src/tbox/src/tbox/xml/reader.h b/core/src/tbox/src/tbox/xml/reader.h
deleted file mode 100644
index 29a2a7068..000000000
--- a/core/src/tbox/src/tbox/xml/reader.h
+++ /dev/null
@@ -1,298 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file reader.h
- * @ingroup xml
- *
- */
-#ifndef TB_XML_READER_H
-#define TB_XML_READER_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-#include "node.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the xml reader event type for iterator
-typedef enum __tb_xml_reader_event_t
-{
- TB_XML_READER_EVENT_NONE = 0
-, TB_XML_READER_EVENT_DOCUMENT_TYPE = 1
-, TB_XML_READER_EVENT_DOCUMENT = 2
-, TB_XML_READER_EVENT_ELEMENT_BEG = 3
-, TB_XML_READER_EVENT_ELEMENT_END = 4
-, TB_XML_READER_EVENT_ELEMENT_EMPTY = 5
-, TB_XML_READER_EVENT_COMMENT = 6
-, TB_XML_READER_EVENT_TEXT = 7
-, TB_XML_READER_EVENT_CDATA = 8
-
-}tb_xml_reader_event_t;
-
-/// the xml reader ref type
-typedef __tb_typeref__(xml_reader);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init the xml reader
- *
- * @return the reader
- */
-tb_xml_reader_ref_t tb_xml_reader_init(tb_noarg_t);
-
-/*! exit the xml reader
- *
- * @param reader the xml reader
- */
-tb_void_t tb_xml_reader_exit(tb_xml_reader_ref_t reader);
-
-/*! open the xml reader
- *
- * @param reader the xml reader
- * @param stream the stream, will open it if be not opened
- * @param bowner the xml reader is owner of the stream?
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_xml_reader_open(tb_xml_reader_ref_t reader, tb_stream_ref_t stream, tb_bool_t bowner);
-
-/*! clos the xml reader
- *
- * @param reader the xml reader
- */
-tb_void_t tb_xml_reader_clos(tb_xml_reader_ref_t reader);
-
-/*! the next iterator for the xml reader
- *
- * @param reader the xml reader
- * @return the iterator event
- *
- * @code
- *
- // init reader
- tb_xml_reader_ref_t reader = tb_xml_reader_init();
- if (reader)
- {
- // open reader
- if (tb_xml_reader_open(reader, tb_stream_init_from_url(argv[1]), tb_true))
- {
- // goto
- tb_bool_t ok = tb_true;
- if (argv[2]) ok = tb_xml_reader_goto(reader, argv[2]);
-
- // walk
- tb_size_t event = TB_XML_READER_EVENT_NONE;
- while (ok && (event = tb_xml_reader_next(reader)))
- {
- switch (event)
- {
- case TB_XML_READER_EVENT_DOCUMENT:
- {
- tb_printf("<?xml version = \"%s\" encoding = \"%s\" ?>\n"
- , tb_xml_reader_version(reader), tb_xml_reader_charset(reader));
- }
- break;
- case TB_XML_READER_EVENT_DOCUMENT_TYPE:
- {
- tb_printf("<!DOCTYPE>\n");
- }
- break;
- case TB_XML_READER_EVENT_ELEMENT_EMPTY:
- {
- tb_char_t const* name = tb_xml_reader_element(reader);
- tb_xml_node_ref_t attr = tb_xml_reader_attributes(reader);
- tb_size_t t = tb_xml_reader_level(reader);
- while (t--) tb_printf("\t");
- if (!attr) tb_printf("<%s/>\n", name);
- else
- {
- tb_printf("<%s", name);
- for (; attr; attr = attr->next)
- tb_printf(" %s = \"%s\"", tb_string_cstr(&attr->name), tb_string_cstr(&attr->data));
- tb_printf("/>\n");
- }
- }
- break;
- case TB_XML_READER_EVENT_ELEMENT_BEG:
- {
- tb_char_t const* name = tb_xml_reader_element(reader);
- tb_xml_node_ref_t attr = tb_xml_reader_attributes(reader);
- tb_size_t t = tb_xml_reader_level(reader) - 1;
- while (t--) tb_printf("\t");
- if (!attr) tb_printf("<%s>\n", name);
- else
- {
- tb_printf("<%s", name);
- for (; attr; attr = attr->next)
- tb_printf(" %s = \"%s\"", tb_string_cstr(&attr->name), tb_string_cstr(&attr->data));
- tb_printf(">\n");
- }
- }
- break;
- case TB_XML_READER_EVENT_ELEMENT_END:
- {
- tb_size_t t = tb_xml_reader_level(reader);
- while (t--) tb_printf("\t");
- tb_printf("</%s>\n", tb_xml_reader_element(reader));
- }
- break;
- case TB_XML_READER_EVENT_TEXT:
- {
- tb_size_t t = tb_xml_reader_level(reader);
- while (t--) tb_printf("\t");
- tb_printf("%s", tb_xml_reader_text(reader));
- tb_printf("\n");
- }
- break;
- case TB_XML_READER_EVENT_CDATA:
- {
- tb_size_t t = tb_xml_reader_level(reader);
- while (t--) tb_printf("\t");
- tb_printf("<![CDATA[%s]]>", tb_xml_reader_cdata(reader));
- tb_printf("\n");
- }
- break;
- case TB_XML_READER_EVENT_COMMENT:
- {
- tb_size_t t = tb_xml_reader_level(reader);
- while (t--) tb_printf("\t");
- tb_printf("<!--%s-->", tb_xml_reader_comment(reader));
- tb_printf("\n");
- }
- break;
- default:
- break;
- }
- }
- }
-
- // exit reader
- tb_xml_reader_exit(reader);
- }
-
- * @endcode
- */
-tb_size_t tb_xml_reader_next(tb_xml_reader_ref_t reader);
-
-/*! the xml stream
- *
- * @param reader the xml reader
- * @return the xml stream
- */
-tb_stream_ref_t tb_xml_reader_stream(tb_xml_reader_ref_t reader);
-
-/*! the xml level
- *
- * @param reader the xml reader
- * @return the xml level for tab spaces
- */
-tb_size_t tb_xml_reader_level(tb_xml_reader_ref_t reader);
-
-/*! seek to the given node for xml, .e.g /root/node/item
- *
- * @param reader the reader handle
- * @param path the xml path
- * @return tb_true or tb_false
- *
- * @note the stream will be reseted
- */
-tb_bool_t tb_xml_reader_goto(tb_xml_reader_ref_t reader, tb_char_t const* path);
-
-/*! load the xml
- *
- * @param reader the xml reader
- * @return the xml root node
- */
-tb_xml_node_ref_t tb_xml_reader_load(tb_xml_reader_ref_t reader);
-
-/*! the xml version
- *
- * @param reader the xml reader
- * @return the xml version
- */
-tb_char_t const* tb_xml_reader_version(tb_xml_reader_ref_t reader);
-
-/*! the xml charset
- *
- * @param reader the xml reader
- * @return the xml charset
- */
-tb_char_t const* tb_xml_reader_charset(tb_xml_reader_ref_t reader);
-
-/*! the current xml element name
- *
- * @param reader the xml reader
- * @return the current xml element name
- */
-tb_char_t const* tb_xml_reader_element(tb_xml_reader_ref_t reader);
-
-/*! the current xml node text
- *
- * @param reader the xml reader
- * @return the current xml node text
- */
-tb_char_t const* tb_xml_reader_text(tb_xml_reader_ref_t reader);
-
-/*! the current xml node cdata
- *
- * @param reader the xml reader
- * @return the current xml node cdata
- */
-tb_char_t const* tb_xml_reader_cdata(tb_xml_reader_ref_t reader);
-
-/*! the current xml node comment
- *
- * @param reader the xml reader
- * @return the current xml node comment
- */
-tb_char_t const* tb_xml_reader_comment(tb_xml_reader_ref_t reader);
-
-/*! the xml document type
- *
- * @param reader the xml reader
- * @return the xml document type
- */
-tb_char_t const* tb_xml_reader_doctype(tb_xml_reader_ref_t reader);
-
-/*! the current xml node attributes
- *
- * @param reader the xml reader
- * @return the current xml node attributes
- */
-tb_xml_node_ref_t tb_xml_reader_attributes(tb_xml_reader_ref_t reader);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/xml/writer.c b/core/src/tbox/src/tbox/xml/writer.c
deleted file mode 100644
index 63b1342b2..000000000
--- a/core/src/tbox/src/tbox/xml/writer.c
+++ /dev/null
@@ -1,497 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file writer.c
- * @ingroup xml
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "xml"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "writer.h"
-#include "../charset/charset.h"
-#include "../algorithm/algorithm.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * macros
- */
-#ifdef __tb_small__
-# define TB_XML_WRITER_ELEMENTS_GROW (32)
-#else
-# define TB_XML_WRITER_ELEMENTS_GROW (64)
-#endif
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the xml writer impl type
-typedef struct __tb_xml_writer_impl_t
-{
- // stream
- tb_stream_ref_t stream;
-
- // is format?
- tb_bool_t bformat;
-
- // is owner of the stream?
- tb_bool_t bowner;
-
- // the elements stack
- tb_stack_ref_t elements;
-
- // the attributes hash
- tb_hash_map_ref_t attributes;
-
-}tb_xml_writer_impl_t;
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-tb_xml_writer_ref_t tb_xml_writer_init()
-{
- // done
- tb_bool_t ok = tb_false;
- tb_xml_writer_impl_t* writer = tb_null;
- do
- {
- // make writer
- writer = tb_malloc0_type(tb_xml_writer_impl_t);
- tb_assert_and_check_break(writer);
-
- // init elements
- writer->elements = tb_stack_init(TB_XML_WRITER_ELEMENTS_GROW, tb_element_str(tb_false));
- tb_assert_and_check_break(writer->elements);
-
- // init attributes
- writer->attributes = tb_hash_map_init(TB_HASH_MAP_BUCKET_SIZE_MICRO, tb_element_str(tb_false), tb_element_str(tb_false));
- tb_assert_and_check_break(writer->attributes);
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed?
- if (!ok)
- {
- // exit it
- if (writer) tb_xml_writer_exit((tb_xml_writer_ref_t)writer);
- writer = tb_null;
- }
-
- // ok?
- return (tb_xml_writer_ref_t)writer;
-}
-tb_void_t tb_xml_writer_exit(tb_xml_writer_ref_t writer)
-{
- // check
- tb_xml_writer_impl_t* impl = (tb_xml_writer_impl_t*)writer;
- tb_assert_and_check_return(impl);
-
- // clos it first
- tb_xml_writer_clos(writer);
-
- // exit attributes
- if (impl->attributes) tb_hash_map_exit(impl->attributes);
- impl->attributes = tb_null;
-
- // exit elements
- if (impl->elements) tb_stack_exit(impl->elements);
- impl->elements = tb_null;
-
- // free it
- tb_free(impl);
-}
-tb_bool_t tb_xml_writer_open(tb_xml_writer_ref_t writer, tb_bool_t bformat, tb_stream_ref_t stream, tb_bool_t bowner)
-{
- // check
- tb_xml_writer_impl_t* impl = (tb_xml_writer_impl_t*)writer;
- tb_assert_and_check_return_val(impl && stream, tb_false);
-
- // done
- tb_bool_t ok = tb_false;
- do
- {
- // check
- tb_assert_and_check_break(!impl->stream);
-
- // init format
- impl->bformat = bformat;
-
- // init owner
- impl->bowner = bowner;
-
- // init stream
- impl->stream = stream;
-
- // ctrl stream
- if (tb_stream_type(stream) == TB_STREAM_TYPE_FILE)
- {
- // ctrl mode
- if (!tb_stream_ctrl(stream, TB_STREAM_CTRL_FILE_SET_MODE, TB_FILE_MODE_RW | TB_FILE_MODE_CREAT | TB_FILE_MODE_TRUNC)) break;
- }
-
- // open the reader stream if be not opened
- if (!tb_stream_is_opened(impl->stream) && !tb_stream_open(impl->stream)) break;
-
- // ok
- ok = tb_true;
-
- } while (0);
-
- // failed? close it
- if (!ok) tb_xml_writer_clos(writer);
-
- // ok?
- return ok;
-}
-tb_void_t tb_xml_writer_clos(tb_xml_writer_ref_t writer)
-{
- // check
- tb_xml_writer_impl_t* impl = (tb_xml_writer_impl_t*)writer;
- tb_assert_and_check_return(impl);
-
- // clos stream
- if (impl->stream) tb_stream_clos(impl->stream);
-
- // exit stream
- if (impl->stream && impl->bowner) tb_stream_exit(impl->stream);
- impl->stream = tb_null;
-
- // clear owner
- impl->bowner = tb_false;
-
- // clear format
- impl->bformat = tb_false;
-
- // clear attributes
- if (impl->attributes) tb_hash_map_clear(impl->attributes);
-
- // clear elements
- if (impl->elements) tb_stack_clear(impl->elements);
-}
-tb_void_t tb_xml_writer_save(tb_xml_writer_ref_t writer, tb_xml_node_ref_t node)
-{
- // check
- tb_assert_and_check_return(writer && node);
-
- // done
- switch (node->type)
- {
- case TB_XML_NODE_TYPE_DOCUMENT:
- {
- // document
- tb_xml_document_t* document = (tb_xml_document_t*)node;
- tb_xml_writer_document(writer, tb_string_cstr(&document->version), tb_string_cstr(&document->charset));
-
- // childs
- tb_xml_node_ref_t next = node->chead;
- while (next)
- {
- // save
- tb_xml_writer_save(writer, next);
-
- // next
- next = next->next;
- }
- }
- break;
- case TB_XML_NODE_TYPE_DOCUMENT_TYPE:
- {
- // document type
- tb_xml_document_type_t* doctype = (tb_xml_document_type_t*)node;
- tb_xml_writer_document_type(writer, tb_string_cstr(&doctype->type));
- }
- break;
- case TB_XML_NODE_TYPE_ELEMENT:
- {
- // attributes
- tb_xml_node_ref_t attr = node->ahead;
- while (attr)
- {
- // save
- tb_xml_writer_attributes_cstr(writer, tb_string_cstr(&attr->name), tb_string_cstr(&attr->data));
-
- // next
- attr = attr->next;
- }
-
- // childs
- tb_xml_node_ref_t next = node->chead;
- if (next)
- {
- // enter
- tb_xml_writer_element_enter(writer, tb_string_cstr(&node->name));
-
- // init
- while (next)
- {
- // save
- tb_xml_writer_save(writer, next);
-
- // next
- next = next->next;
- }
-
- // leave
- tb_xml_writer_element_leave(writer);
- }
- else tb_xml_writer_element_empty(writer, tb_string_cstr(&node->name));
- }
- break;
- case TB_XML_NODE_TYPE_COMMENT:
- tb_xml_writer_comment(writer, tb_string_cstr(&node->data));
- break;
- case TB_XML_NODE_TYPE_CDATA:
- tb_xml_writer_cdata(writer, tb_string_cstr(&node->data));
- break;
- case TB_XML_NODE_TYPE_TEXT:
- tb_xml_writer_text(writer, tb_string_cstr(&node->data));
- break;
- default:
- break;
- }
-}
-tb_void_t tb_xml_writer_document(tb_xml_writer_ref_t writer, tb_char_t const* version, tb_char_t const* charset)
-{
- // check
- tb_xml_writer_impl_t* impl = (tb_xml_writer_impl_t*)writer;
- tb_assert_and_check_return(impl && impl->stream);
-
- tb_stream_printf(impl->stream, "<?xml version=\"%s\" encoding=\"%s\"?>", version? version : "2.0", charset? charset : "utf-8");
- if (impl->bformat) tb_stream_printf(impl->stream, "\n");
-}
-tb_void_t tb_xml_writer_document_type(tb_xml_writer_ref_t writer, tb_char_t const* type)
-{
- // check
- tb_xml_writer_impl_t* impl = (tb_xml_writer_impl_t*)writer;
- tb_assert_and_check_return(impl && impl->stream);
-
- tb_stream_printf(impl->stream, "<!DOCTYPE %s>", type? type : "");
- if (impl->bformat) tb_stream_printf(impl->stream, "\n");
-}
-tb_void_t tb_xml_writer_cdata(tb_xml_writer_ref_t writer, tb_char_t const* data)
-{
- // check
- tb_xml_writer_impl_t* impl = (tb_xml_writer_impl_t*)writer;
- tb_assert_and_check_return(impl && impl->stream && data);
-
- // writ tabs
- if (impl->bformat)
- {
- tb_size_t t = tb_stack_size(impl->elements);
- while (t--) tb_stream_printf(impl->stream, "\t");
- }
-
- tb_stream_printf(impl->stream, "<![CDATA[%s]]>", data);
- if (impl->bformat) tb_stream_printf(impl->stream, "\n");
-}
-tb_void_t tb_xml_writer_text(tb_xml_writer_ref_t writer, tb_char_t const* text)
-{
- // check
- tb_xml_writer_impl_t* impl = (tb_xml_writer_impl_t*)writer;
- tb_assert_and_check_return(impl && impl->stream && text);
-
- // writ tabs
- if (impl->bformat)
- {
- tb_size_t t = tb_stack_size(impl->elements);
- while (t--) tb_stream_printf(impl->stream, "\t");
- }
-
- tb_stream_printf(impl->stream, "%s", text);
- if (impl->bformat) tb_stream_printf(impl->stream, "\n");
-}
-tb_void_t tb_xml_writer_comment(tb_xml_writer_ref_t writer, tb_char_t const* comment)
-{
- // check
- tb_xml_writer_impl_t* impl = (tb_xml_writer_impl_t*)writer;
- tb_assert_and_check_return(impl && impl->stream && comment);
-
- // writ tabs
- if (impl->bformat)
- {
- tb_size_t t = tb_stack_size(impl->elements);
- while (t--) tb_stream_printf(impl->stream, "\t");
- }
-
- tb_stream_printf(impl->stream, "<!--%s-->", comment);
- if (impl->bformat) tb_stream_printf(impl->stream, "\n");
-}
-tb_void_t tb_xml_writer_element_empty(tb_xml_writer_ref_t writer, tb_char_t const* name)
-{
- // check
- tb_xml_writer_impl_t* impl = (tb_xml_writer_impl_t*)writer;
- tb_assert_and_check_return(impl && impl->stream && impl->attributes && name);
-
- // writ tabs
- if (impl->bformat)
- {
- tb_size_t t = tb_stack_size(impl->elements);
- while (t--) tb_stream_printf(impl->stream, "\t");
- }
-
- // writ name
- tb_stream_printf(impl->stream, "<%s", name);
-
- // writ attributes
- if (tb_hash_map_size(impl->attributes))
- {
- tb_for_all (tb_hash_map_item_ref_t, item, impl->attributes)
- {
- if (item && item->name && item->data)
- tb_stream_printf(impl->stream, " %s=\"%s\"", item->name, item->data);
- }
- tb_hash_map_clear(impl->attributes);
- }
-
- // writ end
- tb_stream_printf(impl->stream, "/>");
- if (impl->bformat) tb_stream_printf(impl->stream, "\n");
-}
-tb_void_t tb_xml_writer_element_enter(tb_xml_writer_ref_t writer, tb_char_t const* name)
-{
- // check
- tb_xml_writer_impl_t* impl = (tb_xml_writer_impl_t*)writer;
- tb_assert_and_check_return(impl && impl->stream && impl->elements && impl->attributes && name);
-
- // writ tabs
- if (impl->bformat)
- {
- tb_size_t t = tb_stack_size(impl->elements);
- while (t--) tb_stream_printf(impl->stream, "\t");
- }
-
- // writ name
- tb_stream_printf(impl->stream, "<%s", name);
-
- // writ attributes
- if (tb_hash_map_size(impl->attributes))
- {
- tb_for_all (tb_hash_map_item_ref_t, item, impl->attributes)
- {
- if (item && item->name && item->data)
- tb_stream_printf(impl->stream, " %s=\"%s\"", item->name, item->data);
- }
- tb_hash_map_clear(impl->attributes);
- }
-
- // writ end
- tb_stream_printf(impl->stream, ">");
- if (impl->bformat) tb_stream_printf(impl->stream, "\n");
-
- // put name
- tb_stack_put(impl->elements, name);
-}
-tb_void_t tb_xml_writer_element_leave(tb_xml_writer_ref_t writer)
-{
- // check
- tb_xml_writer_impl_t* impl = (tb_xml_writer_impl_t*)writer;
- tb_assert_and_check_return(impl && impl->stream && impl->elements && impl->attributes);
-
- // writ tabs
- if (impl->bformat)
- {
- tb_size_t t = tb_stack_size(impl->elements);
- if (t) t--;
- while (t--) tb_stream_printf(impl->stream, "\t");
- }
-
- // writ name
- tb_char_t const* name = (tb_char_t const*)tb_stack_top(impl->elements);
- tb_assert_and_check_return(name);
-
- tb_stream_printf(impl->stream, "</%s>", name);
- if (impl->bformat) tb_stream_printf(impl->stream, "\n");
-
- // pop name
- tb_stack_pop(impl->elements);
-}
-tb_void_t tb_xml_writer_attributes_long(tb_xml_writer_ref_t writer, tb_char_t const* name, tb_long_t value)
-{
- // check
- tb_xml_writer_impl_t* impl = (tb_xml_writer_impl_t*)writer;
- tb_assert_and_check_return(impl && impl->attributes && name);
-
- tb_char_t data[64] = {0};
- tb_snprintf(data, 64, "%ld", value);
- tb_hash_map_insert(impl->attributes, name, data);
-}
-tb_void_t tb_xml_writer_attributes_bool(tb_xml_writer_ref_t writer, tb_char_t const* name, tb_bool_t value)
-{
- // check
- tb_xml_writer_impl_t* impl = (tb_xml_writer_impl_t*)writer;
- tb_assert_and_check_return(impl && impl->attributes && name);
-
- tb_char_t data[64] = {0};
- tb_snprintf(data, 64, "%s", value? "true" : "false");
- tb_hash_map_insert(impl->attributes, name, data);
-}
-tb_void_t tb_xml_writer_attributes_cstr(tb_xml_writer_ref_t writer, tb_char_t const* name, tb_char_t const* value)
-{
- // check
- tb_xml_writer_impl_t* impl = (tb_xml_writer_impl_t*)writer;
- tb_assert_and_check_return(impl && impl->attributes && name && value);
-
- tb_hash_map_insert(impl->attributes, name, value);
-}
-tb_void_t tb_xml_writer_attributes_format(tb_xml_writer_ref_t writer, tb_char_t const* name, tb_char_t const* format, ...)
-{
- // check
- tb_xml_writer_impl_t* impl = (tb_xml_writer_impl_t*)writer;
- tb_assert_and_check_return(impl && impl->attributes && name && format);
-
- tb_size_t size = 0;
- tb_char_t data[8192] = {0};
- tb_vsnprintf_format(data, 8192, format, &size);
- tb_hash_map_insert(impl->attributes, name, data);
-}
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
-tb_void_t tb_xml_writer_attributes_float(tb_xml_writer_ref_t writer, tb_char_t const* name, tb_float_t value)
-{
- // check
- tb_xml_writer_impl_t* impl = (tb_xml_writer_impl_t*)writer;
- tb_assert_and_check_return(impl && impl->attributes && name);
-
- tb_char_t data[64] = {0};
- tb_snprintf(data, 64, "%f", value);
- tb_hash_map_insert(impl->attributes, name, data);
-}
-tb_void_t tb_xml_writer_attributes_double(tb_xml_writer_ref_t writer, tb_char_t const* name, tb_double_t value)
-{
- // check
- tb_xml_writer_impl_t* impl = (tb_xml_writer_impl_t*)writer;
- tb_assert_and_check_return(impl && impl->attributes && name);
-
- tb_char_t data[64] = {0};
- tb_snprintf(data, 64, "%lf", value);
- tb_hash_map_insert(impl->attributes, name, data);
-}
-#endif
-
diff --git a/core/src/tbox/src/tbox/xml/writer.h b/core/src/tbox/src/tbox/xml/writer.h
deleted file mode 100644
index 6a763db6b..000000000
--- a/core/src/tbox/src/tbox/xml/writer.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file writer.h
- * @ingroup xml
- *
- */
-#ifndef TB_XML_WRITER_H
-#define TB_XML_WRITER_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-#include "node.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_enter__
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-/// the xml writer ref type
-typedef __tb_typeref__(xml_writer);
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * interfaces
- */
-
-/*! init the xml writer
- *
- * @return the writer
- */
-tb_xml_writer_ref_t tb_xml_writer_init(tb_noarg_t);
-
-/*! exit the xml writer
- *
- * @param writer the xml writer
- */
-tb_void_t tb_xml_writer_exit(tb_xml_writer_ref_t writer);
-
-/*! open the xml writer
- *
- * @param writer the xml writer
- * @param bformat is format xml?
- * @param stream the stream, will open it if be not opened
- * @param bowner the xml writer is owner of the stream?
- *
- * @return tb_true or tb_false
- */
-tb_bool_t tb_xml_writer_open(tb_xml_writer_ref_t writer, tb_bool_t bformat, tb_stream_ref_t stream, tb_bool_t bowner);
-
-/*! clos the xml writer
- *
- * @param writer the xml writer
- */
-tb_void_t tb_xml_writer_clos(tb_xml_writer_ref_t writer);
-
-/*! save the xml document or node
- *
- * @param writer the xml writer
- * @param node the xml node
- */
-tb_void_t tb_xml_writer_save(tb_xml_writer_ref_t writer, tb_xml_node_ref_t node);
-
-/*! writ the xml document node: <?xml version = \"...\" encoding = \"...\" ?>
- *
- * @param writer the xml writer
- * @param version the xml version
- * @param encoding the xml encoding
- */
-tb_void_t tb_xml_writer_document(tb_xml_writer_ref_t writer, tb_char_t const* version, tb_char_t const* encoding);
-
-/*! writ the xml document type: <!DOCTYPE type>
- *
- * @param writer the xml writer
- * @param type the xml document type
- */
-tb_void_t tb_xml_writer_document_type(tb_xml_writer_ref_t writer, tb_char_t const* type);
-
-/*! writ the xml cdata: <![CDATA[...]]>
- *
- * @param writer the xml writer
- * @param data the xml cdata
- */
-tb_void_t tb_xml_writer_cdata(tb_xml_writer_ref_t writer, tb_char_t const* data);
-
-/*! writ the xml text
- *
- * @param writer the xml writer
- * @param text the xml text
- */
-tb_void_t tb_xml_writer_text(tb_xml_writer_ref_t writer, tb_char_t const* text);
-
-/*! writ the xml comment: <!-- ... -->
- *
- * @param writer the xml writer
- * @param comment the xml comment
- */
-tb_void_t tb_xml_writer_comment(tb_xml_writer_ref_t writer, tb_char_t const* comment);
-
-/*! writ the empty xml element: <name/>
- *
- * @param writer the xml writer
- * @param name the xml element name
- */
-tb_void_t tb_xml_writer_element_empty(tb_xml_writer_ref_t writer, tb_char_t const* name);
-
-/*! writ the xml element head: <name> ...
- *
- * @param writer the xml writer
- * @param name the xml element name
- */
-tb_void_t tb_xml_writer_element_enter(tb_xml_writer_ref_t writer, tb_char_t const* name);
-
-/*! writ the xml element tail: ... </name>
- *
- * @param writer the xml writer
- */
-tb_void_t tb_xml_writer_element_leave(tb_xml_writer_ref_t writer);
-
-/*! writ the xml attribute for long value
- *
- * @param writer the xml writer
- * @param name the xml attribute name
- * @param value the xml attribute value
- */
-tb_void_t tb_xml_writer_attributes_long(tb_xml_writer_ref_t writer, tb_char_t const* name, tb_long_t value);
-
-/*! writ the xml attribute for boolean value
- *
- * @param writer the xml writer
- * @param name the xml attribute name
- * @param value the xml attribute value
- */
-tb_void_t tb_xml_writer_attributes_bool(tb_xml_writer_ref_t writer, tb_char_t const* name, tb_bool_t value);
-
-/*! writ the xml attribute for cstr value
- *
- * @param writer the xml writer
- * @param name the xml attribute name
- * @param value the xml attribute value
- */
-tb_void_t tb_xml_writer_attributes_cstr(tb_xml_writer_ref_t writer, tb_char_t const* name, tb_char_t const* value);
-
-/*! writ the xml attribute for format value
- *
- * @param writer the xml writer
- * @param name the xml attribute name
- * @param format the xml attribute format
- */
-tb_void_t tb_xml_writer_attributes_format(tb_xml_writer_ref_t writer, tb_char_t const* name, tb_char_t const* format, ...);
-
-#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
-/*! writ the xml attribute for float value
- *
- * @param writer the xml writer
- * @param name the xml attribute name
- * @param value the xml attribute value
- */
-tb_void_t tb_xml_writer_attributes_float(tb_xml_writer_ref_t writer, tb_char_t const* name, tb_float_t value);
-
-/*! writ the xml attribute for double value
- *
- * @param writer the xml writer
- * @param name the xml attribute name
- * @param value the xml attribute value
- */
-tb_void_t tb_xml_writer_attributes_double(tb_xml_writer_ref_t writer, tb_char_t const* name, tb_double_t value);
-#endif
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * extern
- */
-__tb_extern_c_leave__
-
-#endif
diff --git a/core/src/tbox/src/tbox/xml/xml.h b/core/src/tbox/src/tbox/xml/xml.h
deleted file mode 100644
index 0fb66a0ed..000000000
--- a/core/src/tbox/src/tbox/xml/xml.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*!The Treasure Box Library
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (C) 2009 - 2017, TBOOX Open Source Group.
- *
- * @author ruki
- * @file xml.h
- * @defgroup xml
- *
- */
-#ifndef TB_XML_H
-#define TB_XML_H
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-#include "node.h"
-#include "reader.h"
-#include "writer.h"
-
-#endif