summaryrefslogtreecommitdiff
path: root/ext/standard/var.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/standard/var.c')
-rw-r--r--ext/standard/var.c391
1 files changed, 391 insertions, 0 deletions
diff --git a/ext/standard/var.c b/ext/standard/var.c
new file mode 100644
index 0000000000..feb277c4c3
--- /dev/null
+++ b/ext/standard/var.c
@@ -0,0 +1,391 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997,1998 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of one of the following licenses: |
+ | |
+ | A) the GNU General Public License as published by the Free Software |
+ | Foundation; either version 2 of the License, or (at your option) |
+ | any later version. |
+ | |
+ | B) the PHP License as published by the PHP Development Team and |
+ | included in the distribution in the file: LICENSE |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of both licenses referred to here. |
+ | If you did not, or have any questions about PHP licensing, please |
+ | contact core@php.net. |
+ +----------------------------------------------------------------------+
+ | Authors: Jani Lehtimäki <jkl@njet.net> |
+ +----------------------------------------------------------------------+
+ */
+
+#ifdef THREAD_SAFE
+#include "tls.h"
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "php.h"
+#include "fopen-wrappers.h"
+#include "reg.h"
+#include "post.h"
+#include "php3_string.h"
+#if HAVE_SETLOCALE
+#include <locale.h>
+#endif
+
+#include "php3_var.h"
+
+void php3api_var_dump(pval *struc, int level)
+{
+ ulong index;
+ char *key;
+ int i, c = 0;
+ pval *data;
+ char buf[512];
+
+ switch (struc->type) {
+ case IS_LONG:
+ i = sprintf(buf, "%*cint(%ld)\n", level, ' ', struc->value.lval);
+ PHPWRITE(&buf[1], i - 1);
+ break;
+
+ case IS_DOUBLE:
+ i = sprintf(buf, "%*cfloat(%g)\n", level, ' ', struc->value.dval);
+ PHPWRITE(&buf[1], i - 1);
+ break;
+
+ case IS_STRING:
+ i = sprintf(buf, "%*cstring(%d) \"", level, ' ', struc->value.str.len);
+ PHPWRITE(&buf[1], i - 1);
+ PHPWRITE(struc->value.str.val, struc->value.str.len);
+ strcpy(buf, "\"\n");
+ PHPWRITE(buf, strlen(buf));
+ break;
+
+ case IS_ARRAY:
+ i = sprintf(buf, "%*carray(%d) {\n", level, ' ', _php3_hash_num_elements(struc->value.ht));
+ PHPWRITE(&buf[1], i - 1);
+ goto head_done;
+
+ case IS_OBJECT:
+ i = sprintf(buf, "%*cobject(%d) {\n", level, ' ', _php3_hash_num_elements(struc->value.ht));
+ PHPWRITE(&buf[1], i - 1);
+ head_done:
+
+ _php3_hash_internal_pointer_reset(struc->value.ht);
+ for (;; _php3_hash_move_forward(struc->value.ht)) {
+ if ((i = _php3_hash_get_current_key(struc->value.ht, &key, &index)) == HASH_KEY_NON_EXISTANT)
+ break;
+ if (c > 0) {
+ strcpy(buf, "\n");
+ PHPWRITE(buf, strlen(buf));
+ }
+ c++;
+ if (_php3_hash_get_current_data(struc->value.ht, (void **) (&data)) != SUCCESS || !data || (data == struc))
+ continue;
+ switch (i) {
+ case HASH_KEY_IS_LONG:{
+ pval d;
+
+ d.type = IS_LONG;
+ d.value.lval = index;
+ php3api_var_dump(&d, level + 2);
+ }
+ break;
+
+ case HASH_KEY_IS_STRING:{
+ pval d;
+
+ d.type = IS_STRING;
+ d.value.str.val = key;
+ d.value.str.len = strlen(key);
+ php3api_var_dump(&d, level + 2);
+ efree(key);
+ }
+ break;
+ }
+ php3api_var_dump(data, level + 2);
+ }
+ i = sprintf(buf, "%*c}\n", level, ' ');
+ PHPWRITE(&buf[1], i - 1);
+ break;
+
+ default:
+ i = sprintf(buf, "%*ci:0\n", level, ' ');
+ PHPWRITE(&buf[1], i - 1);
+ }
+}
+
+
+PHP_FUNCTION(var_dump)
+{
+ pval *struc;
+
+ if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &struc) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ php3api_var_dump(struc, 1);
+}
+
+
+
+#define STR_CAT(P,S,I) {\
+ pval *__p = (P);\
+ ulong __i = __p->value.str.len;\
+ __p->value.str.len += (I);\
+ if (__p->value.str.val) {\
+ __p->value.str.val = (char *)erealloc(__p->value.str.val, __p->value.str.len + 1);\
+ } else {\
+ __p->value.str.val = emalloc(__p->value.str.len + 1);\
+ *__p->value.str.val = 0;\
+ }\
+ strcat(__p->value.str.val + __i, (S));\
+}
+
+
+void php3api_var_serialize(pval *buf, pval *struc)
+{
+ char s[256];
+ ulong slen;
+ int i, ch;
+
+ switch (struc->type) {
+ case IS_LONG:
+ slen = sprintf(s, "i:%ld;", struc->value.lval);
+ STR_CAT(buf, s, slen);
+ return;
+
+ case IS_DOUBLE:
+ slen = sprintf(s, "d:%g;", struc->value.dval);
+ STR_CAT(buf, s, slen);
+ return;
+
+ case IS_STRING:{
+ char *p;
+
+ i = buf->value.str.len;
+ slen = sprintf(s, "s:%d:\"", struc->value.str.len);
+ STR_CAT(buf, s, slen + struc->value.str.len + 2);
+ p = buf->value.str.val + i + slen;
+ if (struc->value.str.len > 0) {
+ memcpy(p, struc->value.str.val, struc->value.str.len);
+ p += struc->value.str.len;
+ }
+ *p++ = '\"';
+ *p++ = ';';
+ *p = 0;
+ }
+ return;
+
+ case IS_ARRAY:
+ ch = 'a';
+ goto got_array;
+
+ case IS_OBJECT:
+ ch = 'o';
+
+ got_array:
+ i = _php3_hash_num_elements(struc->value.ht);
+ slen = sprintf(s, "%c:%d:{", ch, i);
+ STR_CAT(buf, s, slen);
+ if (i > 0) {
+ char *key;
+ pval *data;
+ pval d;
+ ulong index;
+
+ _php3_hash_internal_pointer_reset(struc->value.ht);
+ for (;; _php3_hash_move_forward(struc->value.ht)) {
+ if ((i = _php3_hash_get_current_key(struc->value.ht, &key, &index)) == HASH_KEY_NON_EXISTANT) {
+ break;
+ }
+ if (_php3_hash_get_current_data(struc->value.ht, (void **) (&data)) != SUCCESS || !data || (data == struc)) {
+ continue;
+ }
+ switch (i) {
+ case HASH_KEY_IS_LONG:
+ d.type = IS_LONG;
+ d.value.lval = index;
+ php3api_var_serialize(buf, &d);
+ break;
+ case HASH_KEY_IS_STRING:
+ d.type = IS_STRING;
+ d.value.str.val = key;
+ d.value.str.len = strlen(key);
+ php3api_var_serialize(buf, &d);
+ efree(key);
+ break;
+ }
+ php3api_var_serialize(buf, data);
+ }
+ }
+ STR_CAT(buf, "}", 1);
+ return;
+
+ default:
+ STR_CAT(buf, "i:0;", 4);
+ return;
+ }
+}
+
+
+int php3api_var_unserialize(pval *rval, char **p, char *max)
+{
+ char *q;
+ char *str;
+ int i;
+
+ switch (**p) {
+ case 'i':
+ if (*((*p) + 1) != ':') {
+ return 0;
+ }
+ q = *p;
+ while (**p && **p != ';') {
+ (*p)++;
+ }
+ if (**p != ';') {
+ return 0;
+ }
+ (*p)++;
+ rval->type = IS_LONG;
+ rval->value.lval = atol(q + 2);
+ return 1;
+
+ case 'd':
+ if (*((*p) + 1) != ':') {
+ return 0;
+ }
+ q = *p;
+ while (**p && **p != ';') {
+ (*p)++;
+ }
+ if (**p != ';') {
+ return 0;
+ }
+ (*p)++;
+ rval->type = IS_DOUBLE;
+ rval->value.dval = atof(q + 2);
+ return 1;
+
+ case 's':
+ if (*((*p) + 1) != ':') {
+ return 0;
+ }
+ (*p) += 2;
+ q = *p;
+ while (**p && **p != ':') {
+ (*p)++;
+ }
+ if (**p != ':') {
+ return 0;
+ }
+ i = atoi(q);
+ if (i < 0 || (*p + 3 + i) > max || *((*p) + 1) != '\"' ||
+ *((*p) + 2 + i) != '\"' || *((*p) + 3 + i) != ';') {
+ return 0;
+ }
+ (*p) += 2;
+ str = emalloc(i + 1);
+ if (i > 0) {
+ memcpy(str, *p, i);
+ }
+ str[i] = 0;
+ (*p) += i + 2;
+ rval->type = IS_STRING;
+ rval->value.str.val = str;
+ rval->value.str.len = i;
+ return 1;
+
+ case 'a':
+ rval->type = IS_ARRAY;
+ goto got_array;
+
+ case 'o':
+ rval->type = IS_OBJECT;
+
+ got_array:
+ (*p) += 2;
+ i = atoi(*p);
+ rval->value.ht = (HashTable *) emalloc(sizeof(HashTable));
+ _php3_hash_init(rval->value.ht, i + 1, NULL, PVAL_DESTRUCTOR, 0);
+ while (**p && **p != ':') {
+ (*p)++;
+ }
+ if (**p != ':' || *((*p) + 1) != '{') {
+ return 0;
+ }
+ for ((*p) += 2; **p && **p != '}' && i > 0; i--) {
+ pval key;
+ pval data;
+
+ if (!php3api_var_unserialize(&key, p, max)) {
+ return 0;
+ }
+ if (!php3api_var_unserialize(&data, p, max)) {
+ return 0;
+ }
+ switch (key.type) {
+ case IS_LONG:
+ _php3_hash_index_update(rval->value.ht, key.value.lval, &data, sizeof(data), NULL);
+ break;
+ case IS_STRING:
+ _php3_hash_add(rval->value.ht, key.value.str.val, key.value.str.len + 1, &data, sizeof(data), NULL);
+ break;
+ }
+ pval_destructor(&key);
+ }
+ return *((*p)++) == '}';
+
+ default:
+ return 0;
+ }
+}
+
+
+PHP_FUNCTION(serialize)
+{
+ pval *struc;
+
+ if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &struc) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ return_value->type = IS_STRING;
+ return_value->value.str.val = NULL;
+ return_value->value.str.len = 0;
+ php3api_var_serialize(return_value, struc);
+}
+
+
+PHP_FUNCTION(unserialize)
+{
+ pval *buf;
+
+ if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &buf) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ if (buf->type == IS_STRING) {
+ char *p = buf->value.str.val;
+ if (!php3api_var_unserialize(return_value, &p, p + buf->value.str.len)) {
+ RETURN_FALSE;
+ }
+ } else {
+ RETURN_FALSE;
+ }
+}
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */