Exemplo n.º 1
0
char& string::operator [](int n)
{
	acl_assert(n >= 0);
#if 1
	return (*this)[(size_t) n];
#else
	if (n >= CAP(vbf_))
	{
		int  len = CAP(vbf_);
		printf("%d: cap1: %d\n", __LINE__, CAP(vbf_));
		space(n + 1);
		printf("%d: cap2: %d\n", __LINE__, CAP(vbf_));
		int  new_len = CAP(vbf_);

		// 初始化新分配的内存
		if (new_len > len)
			memset(END(vbf_), 0, new_len - len);

		// 将 vbf_->vbuf.ptr 指向 n 字节处,同时修改 vbf_->vbuf.cnt 值
		ACL_VSTRING_AT_OFFSET(vbf_, n);
	}
	else if (n >= (int) LEN(vbf_))
	{
		ACL_VSTRING_AT_OFFSET(vbf_, n);
		ADDCH(vbf_, '\0');
		TERM(vbf_);
	}

	return (char&) (vbf_->vbuf.data[n]);
#endif
}
Exemplo n.º 2
0
char& string::operator [](size_t n)
{
	// 当偏移位置大于所分配空间的最大位置,需要重新分配内存
	if (n >= (size_t) CAP(vbf_))
	{
		int  len = CAP(vbf_);
		space(n + 1);
		int  new_len = CAP(vbf_);

		// 初始化新分配的内存
		if (new_len > len)
			memset(END(vbf_), 0, new_len - len);

		// 将 vbf_->vbuf.ptr 指向 n 字节处,同时修改 vbf_->vbuf.cnt 值
		ACL_VSTRING_AT_OFFSET(vbf_, (int) n);
	}
	// 当偏移位置大于当前数据长度时,通过重置指针位置以修改数据长度,
	// 这样当调用 length() 方法时可以获得长度
	else if (n >= LEN(vbf_))
	{
		ACL_VSTRING_AT_OFFSET(vbf_, (int) n);
		// 因为本函数返回了偏移位置 n 处的地址引用后,调用者对此引用
		// 地址赋值,但并不会使缓冲区数据长度增加,所以此处在函数返回
		// 前调用 ADDCH 相当于调用者外部赋值后将数据长度加 1
		ADDCH(vbf_, '\0');
		// 保证最后一个字节为 \0
		TERM(vbf_);
	}

	return (char&) (vbf_->vbuf.data[n]);
}
Exemplo n.º 3
0
static const char *xml_parse_meta_text(ACL_XML *xml, const char *data)
{
	int   ch;

	if (LEN(xml->curr_node->text) == 0) {
		SKIP_SPACE(data);
	}

	while ((ch = *data) != 0) {
		if (xml->curr_node->quote) {
			if (ch == xml->curr_node->quote) {
				xml->curr_node->quote = 0;
			}
			ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
		} else if (IS_QUOTE(ch)) {
			if (xml->curr_node->quote == 0) {
				xml->curr_node->quote = ch;
			}
			ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
		} else if (ch == '<') {
			xml->curr_node->nlt++;
			ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
		} else if (ch == '>') {
			if (xml->curr_node->nlt == 0) {
				char *last;
				size_t off;

				data++;
				xml->curr_node->status = ACL_XML_S_MEND;
				if ((xml->curr_node->flag & ACL_XML_F_META_QM) == 0)
					break;

				last = acl_vstring_end(xml->curr_node->text) - 1;
				if (last < STR(xml->curr_node->text) || *last != '?')
					break;
				off = ACL_VSTRING_LEN(xml->curr_node->text) - 1;
				if (off == 0)
					break;
				ACL_VSTRING_AT_OFFSET(xml->curr_node->text, off);
				ACL_VSTRING_TERMINATE(xml->curr_node->text);
				xml_meta_attr(xml->curr_node);
				break;
			}
			xml->curr_node->nlt--;
			ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
		} else {
			ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
		}
		data++;
	}

	ACL_VSTRING_TERMINATE(xml->curr_node->text);
	return (data);
}
Exemplo n.º 4
0
static int vstring_extend(ACL_VBUF *bp, ssize_t incr)
{
	const char *myname = "vstring_extend";
	ssize_t used = (ssize_t) (bp->ptr - bp->data), new_len;
	ACL_VSTRING *vp = (ACL_VSTRING *) bp;

	if (vp->maxlen > 0 && (ssize_t) ACL_VSTRING_LEN(vp) >= vp->maxlen) {
		ACL_VSTRING_AT_OFFSET(vp, vp->maxlen - 1);
		ACL_VSTRING_TERMINATE(vp);
		acl_msg_warn("%s(%d), %s: overflow maxlen: %ld, %ld",
			__FILE__, __LINE__, myname, (long) vp->maxlen,
			(long) ACL_VSTRING_LEN(vp));
		bp->flags |= ACL_VBUF_FLAG_EOF;
		return ACL_VBUF_EOF;
	}

#ifdef ACL_WINDOWS
	if (bp->fd == ACL_FILE_INVALID && (bp->flags & ACL_VBUF_FLAG_FIXED))
#else
	if (bp->fd < 0 && (bp->flags & ACL_VBUF_FLAG_FIXED))
#endif
	{
		acl_msg_warn("%s(%d), %s: can't extend fixed buffer",
			__FILE__, __LINE__, myname);
		return ACL_VBUF_EOF;
	}

	/*
	 * Note: vp->vbuf.len is the current buffer size (both on entry and on
	 * exit of this routine). We round up the increment size to the buffer
	 * size to avoid silly little buffer increments. With really large
	 * strings we might want to abandon the length doubling strategy, and
	 * go to fixed increments.
	 */
#ifdef INCR_NO_DOUBLE
	/* below come from redis-server/sds.c/sdsMakeRoomFor, which can
	 * avoid memory double growing too large --- 2015.2.2, zsx
	 */
	new_len = bp->len + incr;
	if (new_len < MAX_PREALLOC)
		new_len *= 2;
	else
		new_len += MAX_PREALLOC;
#else
	new_len = bp->len + (bp->len > incr ? bp->len : incr);
#endif

	if (vp->maxlen > 0 && new_len > vp->maxlen)
		new_len = vp->maxlen;

	if (vp->slice)
		bp->data = (unsigned char *) acl_slice_pool_realloc(
			__FILE__, __LINE__, vp->slice, bp->data, new_len);
	else if (vp->dbuf) {
		const unsigned char *data = bp->data;
		bp->data = (unsigned char *) acl_dbuf_pool_alloc(
			vp->dbuf, new_len);
		memcpy(bp->data, data, used);
		acl_dbuf_pool_free(vp->dbuf, data);
	} else if (bp->fd != ACL_FILE_INVALID) {
#ifdef ACL_UNIX
		acl_off_t off = new_len - 1;
		if (acl_lseek(bp->fd, off, SEEK_SET) != (acl_off_t) off)
			acl_msg_fatal("lseek failed: %s, off: %lld",
				acl_last_serror(), off);
		if (acl_file_write(bp->fd, "\0", 1, 0, NULL, NULL)
			== ACL_VSTREAM_EOF)
		{
			acl_msg_fatal("write error: %s", acl_last_serror());
		}
#endif
	} else
		bp->data = (unsigned char *) acl_myrealloc(bp->data, new_len);

	bp->len = new_len;
	bp->ptr = bp->data + used;
	bp->cnt = bp->len - used;

	return 0;
}