I write a php extension which contains a simple method, and it works well.
I want to call "mysql_connect" method in this method. I have tried to find some documents or some guides ,but failed.
My extension method code is here:
PHP_FUNCTION(wdd_mysql_connect)
{
char *name;
int name_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE)
{
return;
}
php_printf("Hello %s!", name);
// how to call mysql_connect????????
RETURN_TRUE;
}
Basically, you call zend_call_function(). Example of two helper functions to do that:
/* {{{ zval*** get_params_ex(const char *fmt,size_t len, va_list argp) */
static zval*** get_params_ex(const char *fmt, size_t len TSRMLS_DC, va_list argp) {
zval*** params;
size_t i, j;
char *s=NULL;
long l=-1,r=-1;
double d=-1;
zval *z=NULL;
zend_bool b=0;
params = safe_emalloc(len, sizeof(zval**), 0);
if(NULL == params) {
return NULL;
}
for(i=0; i < len; i++) {
params[i] = emalloc(sizeof(zval*));
}
for(i=0; i < len; i++) {
switch(fmt[i]) {
case 's':
s = va_arg(argp, char*);
MAKE_STD_ZVAL(*params[i]);
ZVAL_STRING(*params[i], s, 1);
break;
case 'l':
l = va_arg(argp, long);
MAKE_STD_ZVAL(*params[i]);
ZVAL_LONG(*params[i], l);
break;
case 'd':
d = va_arg(argp, double);
MAKE_STD_ZVAL(*params[i]);
ZVAL_DOUBLE(*params[i], d);
break;
case 'b':
b = va_arg(argp, int);
MAKE_STD_ZVAL(*params[i]);
ZVAL_BOOL(*params[i], b);
break;
case 'r':
r = va_arg(argp, long);
MAKE_STD_ZVAL(*params[i]);
ZVAL_RESOURCE(*params[i], r);
break;
case 'z':
z = va_arg(argp, zval*);
if(NULL != z) {
*params[i] = z;
}
else {
ALLOC_INIT_ZVAL(*params[i]);
}
break;
default:
php_error_docref(NULL TSRMLS_CC, E_CORE_ERROR, "Unexpected character '%c' in format specifier \"%s\"", fmt[i], fmt);
for(j = 0; j < i; j++) {
zval_ptr_dtor(params[j]);
}
efree(params);
return NULL;
}
}
return params;
}
/* }}} */
/* {{{ META_API zval* obj_call_method_internal_ex(zval *obj, zend_class_entry *ce, zend_function *func, zend_class_entry* calling_scope, zend_bool native_null TSRMLS_DC, char* fmt, ...)
* call method func of the object obj of type ce from the specified scope and return the value returned by the calee.
* if native_null is true, and the method returns a IS_NULL zval, then free that zval and return a NULL pointer
* valid format specifiers are [sldbrz] for string, long, double, boolean, resource, zval */
META_API zval* obj_call_method_internal_ex(zval *obj, zend_class_entry *ce, zend_function *func, zend_class_entry* calling_scope,
zend_bool native_null TSRMLS_DC, char* fmt, ...) {
zval ***params;
int argc;
zval *retval_ptr;
zend_fcall_info fci;
zend_fcall_info_cache fcc;
if(NULL != fmt) {
va_list argv;
argc = strlen(fmt);
va_start(argv, fmt);
params = get_params_ex(fmt, argc TSRMLS_CC, argv);
va_end(argv);
}
else {
argc = 0;
params = NULL;
}
retval_ptr = NULL;
fci.size = sizeof(fci);
fci.function_table = EG(function_table);
fci.function_name = NULL;
fci.symbol_table = NULL;
fci.object_ptr = obj;
fci.retval_ptr_ptr = &retval_ptr;
fci.param_count = argc;
fci.params = params;
fci.no_separation = 1;
fcc.initialized = 1;
fcc.function_handler = func;
fcc.object_ptr = obj;
fcc.calling_scope = calling_scope;
fcc.called_scope = ce;
/*if we want the object, and the object is not an object yet, we init it*/
if(func == ce->constructor) {
if(IS_NULL == Z_TYPE_P(obj)) {
object_init_ex(obj, ce);
}
else {
php_error_docref(NULL TSRMLS_CC, E_CORE_ERROR, "Cannot create an object");
native_null = 1;
goto clean_params;
}
}
if(FAILURE == zend_call_function(&fci, &fcc TSRMLS_CC)) {
php_error_docref(NULL TSRMLS_CC, E_CORE_ERROR, "Cannot call %s::%s", ce->name, func->common.function_name);
if(NULL != retval_ptr) {
zval_ptr_dtor(&retval_ptr);
}
}
clean_params:
if(NULL != params) {
int i;
for(i=0; i < argc; i++) {
zval_ptr_dtor(params[i]);
efree(params[i]);
}
efree(params);
}
if(func == ce->constructor) {
zval_ptr_dtor(&retval_ptr);
retval_ptr = fci.object_ptr;
}
else {
if(native_null) {
if(NULL != retval_ptr && IS_NULL == Z_TYPE_P(retval_ptr)) {
zval_ptr_dtor(&retval_ptr);
retval_ptr = NULL;
}
else {
php_error_docref(NULL TSRMLS_CC, E_CORE_ERROR, "The call %s::%s() does not return NULL as expected", ce->name, func->common.function_name);
}
}
}
return retval_ptr;
}
/* }}} */
Related
I am getting segmentation fault in zend_call_function() and I am not sure what is wrong with my code. If I comment zend_call_function() core dump doesn't happen.
This function is basically responsible for mapping user functions defined in user code or if not defined check in EG scope .
My code looks like:
#if PHP_VERSION_ID >= 70000
static zend_always_inline zval *tracing_call_user_method_va(zval *object, const char *name, size_t name_len, zval **retval_ptr_ptr TSRMLS_DC, uint32_t params_count, va_list passed_params)
{
int result;
uint32_t i;
zend_fcall_info fci;
zend_fcall_info_cache fcc;
zend_class_entry *obj_ce;
HashTable *function_table;
zend_string *lc_name;
zval retval, *params = NULL, **orig_params;
zval *retval_ptr = *retval_ptr_ptr;
ALLOCA_FLAG(use_heap0);
ALLOCA_FLAG(use_heap1);
if (params_count) {
params = (zval*)do_alloca(sizeof(zval)*params_count, use_heap0);
orig_params = (zval **)do_alloca(sizeof(zval*)*params_count, use_heap1);
for (i = 0; i < params_count; i++) {
zval *val = va_arg(passed_params, zval*);
orig_params[i] = val;
ZVAL_COPY(¶ms[i], val);
}
}
fci.params = params;
fci.object = (object && Z_TYPE_P(object) == IS_OBJECT) ? Z_OBJ_P(object) : NULL;
fci.retval = retval_ptr ? retval_ptr : &retval;
fci.size = sizeof(fci);
#if PHP_VERSION_ID < 70100
fci.symbol_table = NULL;
fci.function_table = NULL;
#endif
fci.param_count = params_count;
#if PHP_VERSION_ID < 80000
fci.no_separation = 1;
#endif
#if PHP_VERSION_ID >= 80000
fci.named_params = NULL;
#endif
obj_ce = object ? Z_OBJCE_P(object) : NULL;
if (obj_ce) {
function_table = &obj_ce->function_table;
} else {
function_table = EG(function_table);
}
lc_name = zend_string_alloc(name_len, 0);
zend_str_tolower_copy(ZSTR_VAL(lc_name), name, name_len);
if (UNEXPECTED((fcc.function_handler = zend_hash_find_ptr(function_table, lc_name)) == NULL)) {
ZVAL_STRINGL(&fci.function_name, name, name_len);
result = zend_call_function(&fci, NULL);
zval_ptr_dtor(&fci.function_name);
} else {
#if PHP_VERSION_ID < 70300
fcc.initialized = 1;
#endif
fcc.calling_scope = obj_ce;
if (object) {
fcc.called_scope = Z_OBJCE_P(object);
} else {
zend_class_entry *called_scope = zend_get_called_scope(EG(current_execute_data));
if (obj_ce &&
(!called_scope ||
!instanceof_function(called_scope, obj_ce))) {
fcc.called_scope = obj_ce;
} else {
fcc.called_scope = called_scope;
}
}
fcc.object = object ? Z_OBJ_P(object) : NULL;
result = zend_call_function(&fci, &fcc TSRMLS_CC);
}
zend_string_release(lc_name);
if (result == FAILURE) {
if (!EG(exception)) {
php_error_docref(NULL, E_WARNING, "Couldn't trace method %s%s%s", obj_ce ? ZSTR_VAL(obj_ce->name) : "", obj_ce ? "::" : "", name);
}
}
for (i = 0; i < params_count; i++) {
if (Z_ISREF(params[i]) && !Z_ISREF_P(orig_params[i])) {
ZVAL_COPY_VALUE(orig_params[i], ¶ms[i]);
}
zval_ptr_dtor(¶ms[i]);
}
if (params_count) {
free_alloca(orig_params, use_heap0);
free_alloca(params, use_heap1);
}
if (!retval_ptr) {
zval_ptr_dtor(&retval);
return NULL;
}
return retval_ptr;
}
The segmentation fault backtrace is :
024+ # 1: /lib64/libc.so.6(+0x36400) [0x7f0bdc2f2400]
025+ # 2: /usr/local/bin/php() [0xe35a17]
026+ # 3: /usr/local/bin/php() [0xe35ee3]
027+ # 4: /usr/local/bin/php(zval_ptr_dtor+0x36) [0xe36394]
028+ # 5: /usr/local/bin/php() [0xc1054d]
029+ # 6: /usr/local/bin/php(zend_call_function+0xee5) [0xe16044]
i'm trying to send multiple data to a webserver using Ethercard library but for any reason is is only sending one data at a time.
Here is the the code I'm using:
#include <enc28j60.h>
#include <EtherCard.h>
#include <net.h>
#define HTTP_HEADER_OFFSET 163
#define MAX_STRINGS 100
#define MAX_STRING_LENGTH 8
/* Setup for Ethernet Library */
static byte mymac[] = { 0x74, 0x69, 0x69, 0x2D, 0x30, 0x31 };
const char website[] PROGMEM = "www.arksecurity.net16.net";
const char device[] = "0004";
char test[MAX_STRINGS][MAX_STRING_LENGTH+1];
unsigned long timer;
unsigned long tempo = 5000;
String register[20];
unsigned int sentOK = 0;
char* localID[MAX_STRINGS];
int countRegister = 2;
//int countRegister = 1;
int countID;
byte Ethernet::buffer[700];
void setup()
{
Serial.begin(57600);
register[0] = "empty";
if (!ether.begin(sizeof Ethernet::buffer, mymac, 53))
{
Serial.println("Failed to access Ethernet controller");
while(1);
}
else
Serial.println("Ethernet controller initialized");
Serial.println();
if (!ether.dhcpSetup())
{
Serial.println("Failed to get configuration from DHCP");
while(1);
}
else
Serial.println("DHCP configuration done");
if (!ether.dnsLookup(website))
{
Serial.println("DNS failed");
while(1);
}
else
Serial.println("DNS resolution done");
ether.printIp("SRV IP:\t", ether.hisip);
Serial.println();
timer = millis() - tempo;
}
void loop()
{
char tempRegister[80];
ether.packetLoop(ether.packetReceive());
if (millis() - timer > tempo)
{
timer += tempo;
ether.browseUrl(PSTR("/DevicesQuery.php?device="), device , website, response_callback);
if(test[0][0] != 0)
{
int missing = 0;
Serial.println("Data Received");
for(int i = 0; i < countID ; i++)
{
for(int x = 0; x < 8 ; x++)
{
if (test[i][x] == '\0')
{
missing = 1;
}
}
}
if(missing)
{
Serial.println("Data Missing");
tempo = 5000;
}
else
{
for(int g; g < countID ; g++)
{
register[g] = String(test[g]);
}
tempo = 40000;
}
}
else{
Serial.println("Waiting for server response...");
tempo = 5000;
}
//register[0] = "?ID=1234";
//register[1] = "?ID=5678";
if(register[0] != "empty")
{
for(int i = 0; i < countRegister ; i++)
{
register[i].toCharArray(tempRegister, 80);
//delay(5000);
//Serial.println(tempRegister);
ether.browseUrl(PSTR("/log.php"), tempRegister , website, browser_callback);
//while(sentOK == 0);
//sentOK = 0;
}
countRegister = 0;
register[0] = "empty";
}
}
}
static void response_callback (byte status, word off, word len) {
for(int i=0;i<MAX_STRINGS;i++)
for(int j=0;j<=MAX_STRING_LENGTH;j++)
test[i][j] = 0;
int i_string = 0;
int i_char = 0;
int i_ethBuff = off + HTTP_HEADER_OFFSET;
char carat;
countID = 0;
for (i_ethBuff = off + HTTP_HEADER_OFFSET; (carat = (char)Ethernet::buffer[i_ethBuff]) != 0; i_ethBuff++)
{
if (carat == '\n')
{ // New line char = new string
if (i_string < MAX_STRINGS - 1){
i_string++;
i_char = 0;
}
else
break; // Limite de memória do Arduino
}
else
{
if (i_char < MAX_STRING_LENGTH)
{
test[i_string][i_char] = carat;
i_char++;
} // otherwise discard the char (max length of string reached)
}
}
}
static void browser_callback (byte status, word off, word len)
{
Serial.println("Data sent");
//sentOK = 1;
}
countRegister is a variable and when it equals 1, it works great but, if he equals 2,for example, he only sends the second data to the server and ignore the first one. Anyone knows why is happening?
PS.:As for right now, I'm forcing register[0],register[1] values as you can see in the code above,but the idea is that later this values come from an outsource.
The short of it is that browseurl works asynchronously. Have a look at
http://forum.jeelabs.net/node/1477.html
Is there an easy way in PHP to figure out the source code/content of a built in function?
Say for example I want to know what base64_decode() actually does to the given encoded base64 string to convert it to a plain text. How can I achieve this?
You can browse the source code of PHP here
In your case base64_decode is implemented here (PHP 5.6.0)
Note: This code is in C since that's what PHP is written in. In fact all built-in functions and extensions of PHP are written in C.
PHPAPI unsigned char *php_base64_decode_ex(const unsigned char *str, int length, int *ret_length, zend_bool strict) /* {{{ */
{
const unsigned char *current = str;
int ch, i = 0, j = 0, k;
/* this sucks for threaded environments */
unsigned char *result;
result = (unsigned char *)safe_emalloc(length, 1, 1);
/* run through the whole string, converting as we go */
while ((ch = *current++) != '\0' && length-- > 0) {
if (ch == base64_pad) {
if (*current != '=' && ((i % 4) == 1 || (strict && length > 0))) {
if ((i % 4) != 1) {
while (isspace(*(++current))) {
continue;
}
if (*current == '\0') {
continue;
}
}
efree(result);
return NULL;
}
continue;
}
ch = base64_reverse_table[ch];
if ((!strict && ch < 0) || ch == -1) { /* a space or some other separator character, we simply skip over */
continue;
} else if (ch == -2) {
efree(result);
return NULL;
}
switch(i % 4) {
case 0:
result[j] = ch << 2;
break;
case 1:
result[j++] |= ch >> 4;
result[j] = (ch & 0x0f) << 4;
break;
case 2:
result[j++] |= ch >>2;
result[j] = (ch & 0x03) << 6;
break;
case 3:
result[j++] |= ch;
break;
}
i++;
}
k = j;
/* mop things up if we ended on a boundary */
if (ch == base64_pad) {
switch(i % 4) {
case 1:
efree(result);
return NULL;
case 2:
k++;
case 3:
result[k] = 0;
}
}
if(ret_length) {
*ret_length = j;
}
result[j] = '\0';
return result;
}
PHP has a feature where you can use increment operators on strings. It behaves similarly to an odometer, where once you reach the end of a range, it "rolls over".
<?php
$str = 'zy';
$str++;
echo "$str\n"; // zz
$str++;
echo "$str\n"; // aaa
Just curious where in the PHP source code this is. I often look in the source code at functions/extensions, but something like this I have no idea where to look.
A link to the file using their web based SVN would be awesome.
The implementation for this operator is conveniently located in zend_operators.c, in a function that's even more conveniently called increment_string():
static void increment_string(zval *str) /* {{{ */
{
int carry=0;
int pos=Z_STRLEN_P(str)-1;
char *s=Z_STRVAL_P(str);
char *t;
int last=0; /* Shut up the compiler warning */
int ch;
if (Z_STRLEN_P(str) == 0) {
STR_FREE(Z_STRVAL_P(str));
Z_STRVAL_P(str) = estrndup("1", sizeof("1")-1);
Z_STRLEN_P(str) = 1;
return;
}
if (IS_INTERNED(s)) {
s = (char*) emalloc(Z_STRLEN_P(str) + 1);
memcpy(s, Z_STRVAL_P(str), Z_STRLEN_P(str) + 1);
Z_STRVAL_P(str) = s;
}
while (pos >= 0) {
ch = s[pos];
if (ch >= 'a' && ch <= 'z') {
if (ch == 'z') {
s[pos] = 'a';
carry=1;
} else {
s[pos]++;
carry=0;
}
last=LOWER_CASE;
} else if (ch >= 'A' && ch <= 'Z') {
if (ch == 'Z') {
s[pos] = 'A';
carry=1;
} else {
s[pos]++;
carry=0;
}
last=UPPER_CASE;
} else if (ch >= '0' && ch <= '9') {
if (ch == '9') {
s[pos] = '0';
carry=1;
} else {
s[pos]++;
carry=0;
}
last = NUMERIC;
} else {
carry=0;
break;
}
if (carry == 0) {
break;
}
pos--;
}
if (carry) {
t = (char *) emalloc(Z_STRLEN_P(str)+1+1);
memcpy(t+1, Z_STRVAL_P(str), Z_STRLEN_P(str));
Z_STRLEN_P(str)++;
t[Z_STRLEN_P(str)] = '\0';
switch (last) {
case NUMERIC:
t[0] = '1';
break;
case UPPER_CASE:
t[0] = 'A';
break;
case LOWER_CASE:
t[0] = 'a';
break;
}
STR_FREE(Z_STRVAL_P(str));
Z_STRVAL_P(str) = t;
}
}
/* }}} */
I have an actionscript class that serializes and unserializes data compatible with php's serialization functions. I expanded it to support binary data but now the unserialization does not seem to work.
For example, this data is not unserialized correctly:
a:2:{i:0;s:1:"õ";i:1;a:2:{i:0;s:32:"mÎiyl·T=doÁ°ýNd_¤ÁÝ`:AåÁˆ#";i:1;s:32:"ÿ^ò`d^|“T¶&JÐÞG[±iÏ*Ÿ!–Ü’IÍ";}}
Here is the class:
package pack
{
import flash.utils.ByteArray;
import flash.utils.Dictionary;
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.core.*;
use namespace mx_internal;
public class Serializer extends Object
{
public static const version:String = "3.0.0";
mx_internal static var c:uint;
mx_internal static var pattern:RegExp = /[A-Z][a-z]{2}, \d{2} [A-Z][a-z]{2} \d{4} \d{2}:\d{2}:\d{2} \+|\-\d{4}/g
public static function serialize(data:*):ByteArray
{
var bas:ByteArray = new ByteArray();
var tmp:ByteArray = new ByteArray();
var i:int = 0;
var key:String;
if(data is Boolean){
bas.writeUTFBytes('b:');
bas.writeUnsignedInt(data);
bas.writeUTFBytes(';');
} else if(data is int){
bas.writeUTFBytes('i:');
bas.writeUTFBytes(data);
bas.writeUTFBytes(';');
} else if(data is Number){
bas.writeUTFBytes('d:');
bas.writeUTFBytes(data);
bas.writeUTFBytes(';');
} else if(data is ByteArray){
bas.writeUTFBytes('s:');
bas.writeUTFBytes(data.length.toString());
bas.writeUTFBytes(':"');
bas.writeBytes(data);
bas.writeUTFBytes('";');
} else if(data is String){
bas.writeUTFBytes('s:');
bas.writeUTFBytes(data.length.toString());
bas.writeUTFBytes(':"');
bas.writeUTFBytes(data);
bas.writeUTFBytes('";');
} else if(data is Date){
bas.writeUTFBytes('s:');
bas.writeUTFBytes(data.toString().length.toString());
bas.writeUTFBytes(':"');
bas.writeUTFBytes(data);
bas.writeUTFBytes('";');
} else if(data is ArrayCollection){
for(key in data){
tmp.writeBytes(Serializer.serialize(i));
tmp.writeBytes(Serializer.serialize(data[key]));
i += 1;
}
bas.writeUTFBytes('a:');
bas.writeUTFBytes(i.toString());
bas.writeUTFBytes(':{');
bas.writeBytes(tmp);
bas.writeUTFBytes('}');
} else if(data is Array){
for(key in data){
tmp.writeBytes(Serializer.serialize(i));
tmp.writeBytes(Serializer.serialize(data[key]));
i += 1;
}
bas.writeUTFBytes('a:');
bas.writeUTFBytes(i.toString());
bas.writeUTFBytes(':{');
bas.writeBytes(tmp);
bas.writeUTFBytes('}');
} else if(data is Object){
for(key in data){
tmp.writeBytes(Serializer.serialize(key));
tmp.writeBytes(Serializer.serialize(data[key]));
i += 1;
}
bas.writeUTFBytes('O:8:"stdClass":');
bas.writeUTFBytes(i.toString());
bas.writeUTFBytes(':{');
bas.writeBytes(tmp);
bas.writeUTFBytes('}');
} else if(data == null || data == undefined){
bas.writeUTFBytes('N;');
} else {
bas.writeUTFBytes('i:0;');
}
return bas;
}
public static function unserialize(data:ByteArray):*
{
Serializer.c = 0;
return Serializer.unserialize_internal(data);
}
mx_internal static function unserialize_internal(data:ByteArray):*
{
var result:*;
var tmpvar:*;
var tmp:Array = new Array();
var type:String = Serializer.charAt(data, Serializer.c);
var pos:uint = 0;
var islist:Boolean = true;
var i:uint;
switch(type){
case "N":
Serializer.c += 2;
break;
case "b":
result = Serializer.substr(data, Serializer.c+2, 1).toString() == '1'
//result = data.substr(Serializer.c+2, 1) == "1"
Serializer.c += 4
break;
case "i":
tmp.push(Serializer.indexOf(data, ';', Serializer.c));
//tmp.push(data.indexOf(";", Serializer.c))
pos = Serializer.c+2
Serializer.c = tmp[0]+1
result = int(Serializer.substring(data, pos, tmp[0]));
//result = int(data.substring(pos,tmp[0]))
break;
case "d":
tmp.push(Serializer.indexOf(data, ';', Serializer.c));
//tmp.push(data.indexOf(";", Serializer.c))
pos = Serializer.c + 2
Serializer.c = tmp[0]+1
result = Number(Serializer.substring(data, pos, tmp[0]));
//result = Number(data.substring(pos,tmp[0]))
break;
case "s":
tmp.push(int(Serializer.indexOf(data, ':', Serializer.c+2)));
//tmp.push(int(data.indexOf(":", Serializer.c+2)))
tmp.push(tmp[0]+2)
pos = Serializer.c+2
tmp.push(0)
tmp.push(int(Serializer.substring(data, pos, tmp[0])));
//tmp.push(int(data.substring(pos, tmp[0])));
if(tmp[3] == 0)
{
result = "";
Serializer.c = pos+5
} else {
var lenc:uint = Serializer.stringBCLenght(data, Serializer.c, tmp[3]);
if(lenc != tmp[3])
{
result = Serializer.substr(data, tmp[0]+2, lenc);
//result = data.substr(tmp[0]+2, lenc);
Serializer.c = tmp[0]+4+lenc;
} else {
result = Serializer.substr(data, tmp[0]+2, tmp[3]);
//result = data.substr(tmp[0]+2, tmp[3]);
Serializer.c = tmp[0]+4+tmp[3];
}
}
if(Serializer.pattern.test(result))
{
result = new Date(result)
}
break;
case "a":
//result:ByteArray;
pos = Serializer.c+2
tmp.push(int(Serializer.indexOf(data, ":", pos)))
tmp.push(int(Serializer.substring(data, pos, tmp[0])))
//tmp.push(int(data.indexOf(":", pos)))
//tmp.push(int(data.substring(pos, tmp[0])))
Serializer.c = tmp[0]+2
result = []
for(i = 0; i < tmp[1]; i++){
tmpvar = Serializer.unserialize_internal(data)
result[tmpvar] = Serializer.unserialize_internal(data)
if(!(tmpvar is int) || tmpvar < 0){
islist = false
}
}
if(islist){
tmp.push([])
for(var key:uint = 0; key < result.length; key++){
pos = tmp[2].length
while(key > pos){
tmp[2].push(null)
pos +=1
}
tmp[2].push(result[key])
}
result = tmp[2]
}
Serializer.c += 1
break;
case "O":
pos = Serializer.indexOf(data, "\"", Serializer.c)+1;
Serializer.c = Serializer.indexOf(data, "\"", pos);
tmp.push(Serializer.substring(data, pos, Serializer.c))
//pos = data.indexOf("\"", Serializer.c)+1;
//Serializer.c = data.indexOf("\"", pos);
//tmp.push(data.substring(pos, Serializer.c))
Serializer.c += 2
i = Serializer.c
Serializer.c = Serializer.indexOf(data, ":", i)
i = int(Serializer.substring(data, i, Serializer.c))
//Serializer.c = data.indexOf(":", i)
//i = int(data.substring(i, Serializer.c))
Serializer.c +=2;
result = {};
var tmps:*;
while(i > 0){
tmps = Serializer.unserialize_internal(data)
result[tmps] = Serializer.unserialize_internal(data)
i -= 1
}
break;
}
return result;
}
mx_internal static function stringCLenght(data:String, from:uint = 0, len:uint = 0):int
{
var i:uint;
var j:uint = len;
var startIndex:uint = from + 4 + len.toString().length;
for (i = 0; i < j; i++){
if (data.charCodeAt(i+startIndex) > 128)
{
j = j - 1
}
}
return j;
}
mx_internal static function stringBCLenght(data:ByteArray, from:uint = 0, len:uint = 0):int
{
var i:uint;
var j:uint = len;
var startIndex:uint = from + 4 + len.toString().length;
for (i = 0; i < j; i++){
if (Serializer.charCodeAt(data, i+startIndex) > 128)
{
j = j - 1
}
}
return j;
}
mx_internal static function stringLength(data:String):uint
{
var code:int = 0
var result:int = 0
var slen:int = data.length;
while(slen){
slen = slen - 1
try
{
code = data.charCodeAt(slen)
} catch(e:Error){
code = 65536
}
if(code < 128){
result = result + 1
} else if(code < 2048){
result = result + 2
} else if(code < 65536){
result = result + 3
} else {
result = result + 4
}
}
return result
}
public static function charAt(bytes:ByteArray, index:int):String {
if (bytes.length <= index) return null;
return String.fromCharCode(bytes[index]);
}
public static function charCodeAt(bytes:ByteArray, index:int):int {
if (bytes.length <= index) return -1;
return bytes[index];
}
public static function substr(bytes:ByteArray, start:int, length:int=0):ByteArray {
var res:ByteArray = new ByteArray();
bytes.position = start;
bytes.readBytes(res, 0, length);
return res;
}
public static function substring(bytes:ByteArray, start:int, end:int=0):ByteArray {
return substr(bytes, start, end-start);
}
public static function indexOf(bytes:ByteArray, str:String, startIndex:int):int {
var num:int = 0;
for (var i:int=0; i<bytes.length; i++) {
var strPos:int = 0;
while (bytes[i+strPos] == str.charCodeAt(strPos)) {
strPos++;
if (strPos == str.length) {
num++;
if(num == startIndex) {
return i;
}
}
}
}
return -1;
}
}
}
I resolved the issue, no need for answers.