static int ipaddr_cmp(Value *vret, Value *v, RefNode *node) { RefSockAddr *rs1 = Value_vp(*v); RefSockAddr *rs2 = Value_vp(v[1]); if (rs1->addr->sa_family == rs2->addr->sa_family) { const void *p1 = sockaddr_bytes(rs1->addr); const void *p2 = sockaddr_bytes(rs2->addr); int n = sockaddr_bytes_count(rs1->addr); int cmp = memcmp(p1, p2, n); if (cmp != 0) { *vret = int32_Value(cmp); } else { // IPAddrではmask_bitsは常に0 if (rs1->mask_bits < rs2->mask_bits) { *vret = int32_Value(-1); } else if (rs1->mask_bits > rs2->mask_bits) { *vret = int32_Value(1); } else { *vret = int32_Value(0); } } } else { fs->throw_errorf(fs->mod_lang, "ValueError", "IP address families are different"); return FALSE; } return TRUE; }
int map_iterator(Value *vret, Value *v, RefNode *node) { RefMap *rm = Value_vp(*v); int type = FUNC_INT(node); Ref *r = ref_new(cls_mapiter); rm->lock_count++; r->v[INDEX_MAPITER_VAL] = Value_cp(*v); r->v[INDEX_MAPITER_TYPE] = int32_Value(type); r->v[INDEX_MAPITER_PTR] = ptr_Value(NULL); r->v[INDEX_MAPITER_IDX] = int32_Value(0); *vret = vp_Value(r); return TRUE; }
static int conn_exec(Value *vret, Value *v, RefNode *node) { Ref *r = Value_ref(*v); sqlite3 *conn = Value_ptr(r->v[INDEX_SQLITE_CONN]); int result; int count; sqlite3_stmt *stmt = NULL; if (!conn_prepare_sub(&stmt, conn, v)) { return FALSE; } result = sqlite3_step(stmt); if (result != SQLITE_DONE && result != SQLITE_ROW) { // ??? if (result != SQLITE_ERROR_USER) { fs->throw_errorf(mod_sqlite, "SQLiteError", "%s", sqlite3_errmsg(conn)); return FALSE; } //return FALSE; } count = sqlite3_changes(conn); sqlite3_finalize(stmt); *vret = int32_Value(count); return TRUE; }
static int ipaddr_hash(Value *vret, Value *v, RefNode *node) { RefSockAddr *rs = Value_vp(*v); const char *p = sockaddr_bytes(rs->addr); int size = sockaddr_bytes_count(rs->addr); *vret = int32_Value(bytes_hash(p, size)); return TRUE; }
void native_timer_new(int millisec, Ref *r) { UINT_PTR id = SetTimer(NULL, 0, millisec, timeout_callback); Value *v_tmp = GuiHash_add_p(&timer_entry, (const void*)id); *v_tmp = fs->Value_cp(vp_Value(r)); r->v[INDEX_TIMER_ID] = int32_Value(id); r->rh.nref++; }
static int matrix_size(Value *vret, Value *v, RefNode *node) { const RefMatrix *mat = Value_vp(*v); int ret; if (FUNC_INT(node)) { ret = mat->cols; } else { ret = mat->rows; } *vret = int32_Value(ret); return TRUE; }
/* * 基本的にエラーが発生しても例外をださない */ static int socket_write(Value *vret, Value *v, RefNode *node) { Ref *r = Value_ref(*v); RefBytesIO *mb = Value_vp(v[1]); RefFileHandle *fh = Value_vp(r->v[INDEX_FILEIO_HANDLE]); int wrote_size = 0; if (fh->fd_write != -1) { wrote_size = send_fox(fh->fd_write, mb->buf.p, mb->buf.size); } *vret = int32_Value(wrote_size); return TRUE; }
static int vector_hash(Value *vret, Value *v, RefNode *node) { const RefVector *vec = Value_vp(*v); uint32_t *i32 = (uint32_t*)vec->d; int i, size; uint32_t hash = 0; size = vec->size * 2; // sizeof(double) / sizeof(uint32_t) for (i = 0; i < size; i++) { hash = hash * 31 + i32[i]; } *vret = int32_Value(hash & INT32_MAX); return TRUE; }
static int matrix_hash(Value *vret, Value *v, RefNode *node) { int i, size; RefMatrix *mat = Value_vp(*v); uint32_t *i32 = (uint32_t*)mat->d; uint32_t hash = 0; size = mat->rows * mat->cols * 2; // sizeof(double) / sizeof(uint32_t) for (i = 0; i < size; i++) { hash = hash * 31 + i32[i]; } *vret = int32_Value(hash & INT32_MAX); return TRUE; }
static int markdown_heading_level(Value *vret, Value *v, RefNode *node) { Ref *r = Value_vp(*v); Markdown *md = Value_ptr(r->v[INDEX_MARKDOWN_MD]); if (fg->stk_top > v + 1) { int64_t i64 = fs->Value_int64(v[1], NULL); if (i64 < 1 || i64 > 6) { fs->throw_errorf(fs->mod_lang, "ValueError", "Out of range (1 - 6)"); return FALSE; } md->heading_level = (int)i64; } else { *vret = int32_Value(md->heading_level); } return TRUE; }
static int strio_index(Value *vret, Value *v, RefNode *node) { RefBytesIO *mb = Value_bytesio(*v); const char *src_p = mb->buf.p; int src_size = mb->buf.size; int idx = utf8_position(src_p, src_size, Value_int64(v[1], NULL)); if (idx >= 0 && idx < src_size) { int code = utf8_codepoint_at(&src_p[idx]); *vret = int32_Value(code); } else { throw_error_select(THROW_INVALID_INDEX__VAL_INT, v[1], src_size); return FALSE; } return TRUE; }
static int mapiter_next(Value *vret, Value *v, RefNode *node) { Ref *r = Value_ref(*v); RefMap *map = Value_vp(r->v[INDEX_MAPITER_VAL]); int idx = Value_integral(r->v[INDEX_MAPITER_IDX]); HashValueEntry *ep = Value_ptr(r->v[INDEX_MAPITER_PTR]); if (ep != NULL) { ep = ep->next; } while (ep == NULL && idx < map->entry_num) { ep = map->entry[idx]; idx++; } r->v[INDEX_MAPITER_IDX] = int32_Value(idx); r->v[INDEX_MAPITER_PTR] = ptr_Value(ep); if (ep != NULL) { switch (Value_integral(r->v[INDEX_MAPITER_TYPE])) { case ITERATOR_KEY: *vret = Value_cp(ep->key); break; case ITERATOR_VAL: *vret = Value_cp(ep->val); break; default: { Ref *r2 = ref_new(fv->cls_entry); *vret = vp_Value(r2); r2->v[INDEX_ENTRY_KEY] = Value_cp(ep->key); r2->v[INDEX_ENTRY_VAL] = Value_cp(ep->val); break; } } } else { throw_stopiter(); return FALSE; } return TRUE; }
static int vector_size(Value *vret, Value *v, RefNode *node) { const RefVector *vec = Value_vp(*v); *vret = int32_Value(vec->size); return TRUE; }
int map_size(Value *vret, Value *v, RefNode *node) { RefMap *rm = Value_vp(*v); *vret = int32_Value(rm->count); return TRUE; }
static int strio_size(Value *vret, Value *v, RefNode *node) { RefBytesIO *mb = Value_bytesio(*v); *vret = int32_Value(strlen_utf8(mb->buf.p, mb->buf.size)); return TRUE; }
/** * 文字コードを変換しながらStreamに出力する * v : stream (optional,sb==NULLの場合必須) * sb : StrBuf : (optional) */ static int stream_write_sub_s(Value v, StrBuf *sb, const char *s_p, int s_size, RefTextIO *tio) { if (s_size < 0) { s_size = strlen(s_p); } // TODO:未検証 if (v != VALUE_NULL) { RefBytesIO *mb = Value_vp(v); if (mb->rh.type == fs->cls_bytesio) { sb = &mb->buf; } } if (sb != NULL) { // sprintfの場合tio==NULL if (tio == NULL || tio->cs->utf8) { if (!StrBuf_add(sb, s_p, s_size)) { return FALSE; } return TRUE; } else { if (tio->out.ic == (void*)-1) { if (!IconvIO_open(&tio->out, fs->cs_utf8, tio->cs, tio->trans ? "?" : NULL)) { return FALSE; } } if (!IconvIO_conv(&tio->out, sb, s_p, s_size, TRUE, TRUE)) { return FALSE; } return TRUE; } } else { if (tio == NULL || tio->cs->utf8) { return stream_write_data(v, s_p, s_size); } else { Ref *r = Value_ref(v); IconvIO *ic = &tio->out; Value *vmb = &r->v[INDEX_WRITE_MEMIO]; RefBytesIO *mb; int max = Value_integral(r->v[INDEX_WRITE_MAX]); if (max == -1) { throw_error_select(THROW_NOT_OPENED_FOR_WRITE); return FALSE; } if (tio->out.ic == (void*)-1) { if (!IconvIO_open(&tio->out, fs->cs_utf8, tio->cs, tio->trans ? "?" : NULL)) { return FALSE; } } if (*vmb == VALUE_NULL) { *vmb = vp_Value(bytesio_new_sub(NULL, BUFFER_SIZE)); max = BUFFER_SIZE; r->v[INDEX_WRITE_MAX] = int32_Value(max); // STDOUTだけ特別扱い if (fs->cgi_mode) { if (r == Value_vp(fg->v_cio)) { send_headers(); } } } mb = Value_vp(*vmb); ic->inbuf = s_p; ic->inbytesleft = s_size; ic->outbuf = mb->buf.p + mb->buf.size; ic->outbytesleft = max - mb->buf.size; for (;;) { switch (IconvIO_next(ic)) { case ICONV_OK: mb->buf.size = ic->outbuf - mb->buf.p; goto BREAK; case ICONV_OUTBUF: mb->buf.size = ic->outbuf - mb->buf.p; if (!stream_flush_sub(v)) { return FALSE; } ic->outbuf = mb->buf.p; ic->outbytesleft = max; break; case ICONV_INVALID: if (tio->trans) { const char *ptr; if (ic->outbytesleft == 0) { mb->buf.size = ic->outbuf - mb->buf.p; if (!stream_flush_sub(v)) { return FALSE; } ic->outbuf = mb->buf.p; ic->outbytesleft = max; } ptr = ic->inbuf; *ic->outbuf++ = '?'; ic->outbytesleft--; // 1文字進める utf8_next(&ptr, ptr + ic->inbytesleft); ic->inbytesleft -= ptr - ic->inbuf; ic->inbuf = ptr; } else { RefCharset *cs = tio->cs; throw_errorf(fs->mod_lang, "CharsetError", "Cannot convert %U to %S", utf8_codepoint_at(ic->inbuf), cs->name); return FALSE; } break; } } BREAK: return TRUE; } } }