Commits

Ruslan Osmanov committed f4890d4

Add: EventBuffer::substr

Comments (0)

Files changed (6)

 }
 /* }}} */
 
+/* {{{ proto string EventBuffer::substr(int start[, int length]);
+ * Returns portion of the buffer contents specified by
+ * <parameter>start</parameter> and <parameter>length</parameter>
+ */
+PHP_METHOD(EventBuffer, substr)
+{
+	zval               *zbuf   = getThis();
+	php_event_buffer_t *b;
+	long                n_start;
+	long                n_length = -1;
+
+	struct evbuffer_ptr    ptr;
+	struct evbuffer_iovec *pv;
+	int                    n_chunks;
+	long                   n_read   = 0;
+	int                    i;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l",
+				&n_start, &n_length) == FAILURE) {
+		return;
+	}
+
+	PHP_EVENT_FETCH_BUFFER(b, zbuf);
+
+	if (_get_pos(&ptr, n_start, b->buf TSRMLS_CC) == FAILURE) {
+		RETURN_FALSE;
+	}
+
+	/* Disable changes to the front and end of the buffer */
+	evbuffer_freeze(b->buf, 0);
+	evbuffer_freeze(b->buf, 1);
+
+	/* Determine how many chunks we need */
+	n_chunks = evbuffer_peek(b->buf, n_length, &ptr, NULL, 0);
+	/* Allocate space for the chunks. */
+	pv = emalloc(sizeof(struct evbuffer_iovec) * n_chunks);
+	/* Fill up pv */
+	n_chunks = evbuffer_peek(b->buf, n_length, &ptr, pv, n_chunks);
+
+	/* Determine the size of the result string */
+	for (i = 0; i < n_chunks; ++i) {
+		size_t len = pv[i].iov_len;
+
+		if (n_read + len > n_length) {
+			len = n_length - n_read;
+		}
+
+		n_read += len;
+	}
+
+	/* Build result string */
+	Z_TYPE_P(return_value)   = IS_STRING;
+	Z_STRLEN_P(return_value) = n_read;
+	Z_STRVAL_P(return_value) = emalloc(n_read + 1);
+
+	for (n_read = 0, i = 0; i < n_chunks; ++i) {
+		size_t len = pv[i].iov_len;
+
+		if (n_read + len > n_length) {
+			len = n_length - n_read;
+		}
+
+		memcpy(Z_STRVAL_P(return_value) + n_read, pv[i].iov_base, len);
+
+		n_read += len;
+	}
+	Z_STRVAL_P(return_value)[n_read] = '\0';
+
+	efree(pv);
+
+	/* Enable changes to the front and end of the buffer */
+	evbuffer_unfreeze(b->buf, 0);
+	evbuffer_unfreeze(b->buf, 1);
+}
+/* }}} */
+
 /*
  * Local variables:
  * tab-width: 4

classes/buffer_event.c

 	long                port;
 	long                family       = AF_UNSPEC;
 
-#if HAVE_EVENT_EXTRA_LIB
+#ifdef HAVE_EVENT_EXTRA_LIB
 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O!sl|l",
 				&zdns_base, php_event_dns_base_ce, &hostname, &hostname_len,
 				&port, &family) == FAILURE) {
   Fix: build error with zts PHP setup
   Fix: build error with libevent_extra disabled
   Add: EventListener fd readonly property for numeric file descriptor of the socket associated with the listener
+  Add: EventBuffer::substr method
   ]]></notes>
   <!--}}}-->
   <!--{{{ Contents -->
   Fix: build error with zts PHP setup
   Fix: build error with libevent_extra disabled
   Add: EventListener fd readonly property for numeric file descriptor of the socket associated with the listener
+  Add: EventBuffer::substr method
   ]]></notes>
     </release>
     <!--}}}-->
 	ZEND_ARG_INFO(0, howmuch)
 ZEND_END_ARG_INFO();
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_evbuffer_substr, 0, 0, 1)
+	ZEND_ARG_INFO(0, start)
+	ZEND_ARG_INFO(0, length)
+ZEND_END_ARG_INFO();
+
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_event_socket_1, 0, 0, 0)
 	ZEND_ARG_INFO(0, socket)
 	PHP_ME(EventBuffer, searchEol,     arginfo_evbuffer_search_eol,    ZEND_ACC_PUBLIC)
 	PHP_ME(EventBuffer, pullup,        arginfo_evbuffer_pullup,        ZEND_ACC_PUBLIC)
 	PHP_ME(EventBuffer, write,         arginfo_evbuffer_write,         ZEND_ACC_PUBLIC)
+	PHP_ME(EventBuffer, substr,        arginfo_evbuffer_substr,        ZEND_ACC_PUBLIC)
 
 	PHP_FE_END
 };
 PHP_METHOD(EventBuffer, searchEol);
 PHP_METHOD(EventBuffer, pullup);
 PHP_METHOD(EventBuffer, write);
+PHP_METHOD(EventBuffer, substr);
 
 PHP_METHOD(EventUtil, getLastSocketErrno);
 PHP_METHOD(EventUtil, getLastSocketError);

tests/08-buffer.phpt

 $b3 = new EventBuffer();
 $b3->add("123");
 echo "$j ", $b3->search("23", 1, 10) == 1 ? "ok" : "failed", PHP_EOL;
+
+
+$s = "";
+$b4 = new EventBuffer();
+for ($i = 0; $i < 10; ++$i) {
+	$s .= $i;
+}
+$b4->add($s);
+
+$success = TRUE;
+for ($i = 0; $i < 10; ++$i) {
+	for ($j = 1; $j < 10; ++$j) {
+		if ($b4->substr($i, $j) != substr($s, $i, $j)) {
+			$success = FALSE;
+			break;
+		}
+	}
+}
+echo "9 ", $success ? "ok" : "failed";
+
 ?>
 --EXPECT--
 1 ok
 6 ok
 7 ok
 8 ok
+9 ok
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.