void JSON_Get_child_by_name(sLONG_PTR *pResult, PackagePtr pParams)
{
	C_TEXT json;
	C_TEXT name;
	C_LONGINT option;
	C_TEXT returnValue;
	
	json.fromParamAtIndex(pParams, 1);
	name.fromParamAtIndex(pParams, 2);
	option.fromParamAtIndex(pParams, 3);
	
	JSONNODE *n = _fromHex(json);
	
	if(n){
		std::wstring w;
		_copyString(name, w);
		JSONNODE *node = NULL;
		switch (option.getIntValue()) {
			case 1:
				node = json_get_nocase(n, w.c_str());
				break;
			default:
				node = json_get(n, w.c_str());
				break;
		}
		
		_toHex(node, returnValue);
	}
	
	returnValue.setReturn(pResult);
}
void JSON_Append_real_array(sLONG_PTR *pResult, PackagePtr pParams)
{
	C_TEXT json;
	C_TEXT node;
	ARRAY_REAL values;
	C_TEXT returnValue;
	
	json.fromParamAtIndex(pParams, 1);
	node.fromParamAtIndex(pParams, 2);
	values.fromParamAtIndex(pParams, 3);
	
	JSONNODE *n = _fromHex(json);
	
	if(n){
		std::wstring nodeName;
		_copyString(node, nodeName);
		
		JSONNODE *_node = json_new(JSON_ARRAY);
		json_set_name(_node, nodeName.c_str());
		
		for (unsigned int i = 1; i < values.getSize(); ++i) {
			json_push_back(_node, json_new_f(L"", values.getDoubleValueAtIndex(i)));
		}
		
		json_push_back(n, _node);
		_toHex(_node, returnValue);
	}
	
	returnValue.setReturn(pResult);
}
void JSON_GET_TEXT_ARRAY(sLONG_PTR *pResult, PackagePtr pParams)
{
	C_TEXT json;
	ARRAY_TEXT values;
	
	json.fromParamAtIndex(pParams, 1);
	values.setSize(1);
	
	JSONNODE *n = _fromHex(json);
	
	if(n){
		if(json_type(n) == JSON_ARRAY){
			JSONNODE_ITERATOR i = json_begin(n);
			while (i != json_end(n)){
				if (*i){
					json_char *s = json_as_string(*i);
					std::wstring w = std::wstring(s);
					C_TEXT t;
					_copyString(w, t);
					CUTF16String u;
					t.copyUTF16String(&u);
					values.appendUTF16String(&u);
					json_free(s);
				}
				++i;
			}
		}	
	}
	
	values.toParamAtIndex(pParams, 2);
}
void JSON_Export_to_text(sLONG_PTR *pResult, PackagePtr pParams)
{
	C_TEXT json;
	C_LONGINT option;	
	C_TEXT returnValue;
	
	json.fromParamAtIndex(pParams, 1);
	option.fromParamAtIndex(pParams, 2);
	
	JSONNODE *n = _fromHex(json);
	
	json_char *s;
	
	if(n){
		switch (option.getIntValue()) {
			case 1:
				s = json_write(n);
				break;
			default:
				s = json_write_formatted(n);
				break;
		}
		
		std::wstring w = std::wstring(s);
		_copyString(w, returnValue);
		json_free(s);
		
	}
	
	returnValue.setReturn(pResult);
}
void JSON_Strip_white_space(sLONG_PTR *pResult, PackagePtr pParams)
{
	C_TEXT json;
	C_TEXT returnValue;
	
	json.fromParamAtIndex(pParams, 1);
	
	std::wstring w;
	_copyString(json, w);
	json_char *s;
	
	s = json_strip_white_space((const json_char *)w.c_str());
	
	std::wstring j = std::wstring(s);
	_copyString(j, returnValue);
	json_free(s);
	
	returnValue.setReturn(pResult);
}
void JSON_Append_node(sLONG_PTR *pResult, PackagePtr pParams)
{
	C_TEXT json;
	C_TEXT node;
	C_TEXT nodeText;	
	C_TEXT returnValue;
	
	json.fromParamAtIndex(pParams, 1);
	node.fromParamAtIndex(pParams, 2);
	nodeText.fromParamAtIndex(pParams, 3);
	
	JSONNODE *n = _fromHex(json);
	
	if(n){
		std::wstring nodeName;
		_copyString(node, nodeName);
		
		JSONNODE *_node;
		
		if(!nodeText.getUTF16Length()){
			_node = json_new(JSON_NODE);
		}else{
			std::wstring w;
			_copyString(nodeText, w);
			_node = json_parse(w.c_str());
		}
		
		if(_node){
			json_set_name(_node, nodeName.c_str());
			json_push_back(n, _node);
		}
		
		_toHex(_node, returnValue);
	}
	
	returnValue.setReturn(pResult);
}
void JSON_Append_text_array(sLONG_PTR *pResult, PackagePtr pParams)
{
	C_TEXT json;
	C_TEXT node;
	ARRAY_TEXT values;
	C_TEXT returnValue;
	
	json.fromParamAtIndex(pParams, 1);
	node.fromParamAtIndex(pParams, 2);
	values.fromParamAtIndex(pParams, 3);
	
	JSONNODE *n = _fromHex(json);
	
	if(n){
		std::wstring nodeName;
		_copyString(node, nodeName);
		
		JSONNODE *_node = json_new(JSON_ARRAY);
		json_set_name(_node, nodeName.c_str());
		
		for (unsigned int i = 1; i < values.getSize(); ++i) {
			CUTF16String s;
			values.copyUTF16StringAtIndex(&s, i);
			C_TEXT t;
			t.setUTF16String(&s);
			std::wstring valueText;
			_copyString(t, valueText);
			json_push_back(_node, json_new_a(L"", valueText.c_str()));
		}
		
		json_push_back(n, _node);
		_toHex(_node, returnValue);
	}	
	
	returnValue.setReturn(pResult);
}
void JSON_SET_COMMENT(sLONG_PTR *pResult, PackagePtr pParams)
{
	C_TEXT json;
	C_TEXT comment;
	
	json.fromParamAtIndex(pParams, 1);
	comment.fromParamAtIndex(pParams, 2);
	
	JSONNODE *n = _fromHex(json);
	
	if(n){
		std::wstring w;
		_copyString(comment, w);
		json_set_comment(n, w.c_str());	
	}
}
void JSON_SET_NAME(sLONG_PTR *pResult, PackagePtr pParams)
{
	C_TEXT json;
	C_TEXT name;
	
	json.fromParamAtIndex(pParams, 1);
	name.fromParamAtIndex(pParams, 2);
	
	JSONNODE *n = _fromHex(json);
	
	if(n){
		std::wstring w;
		_copyString(name, w);
		json_set_name(n, w.c_str());	
	}
}
void JSON_Get_name(sLONG_PTR *pResult, PackagePtr pParams)
{
	C_TEXT json;
	C_TEXT returnValue;
	
	json.fromParamAtIndex(pParams, 1);
	
	JSONNODE *n = _fromHex(json);
	
	if(n){
		json_char *s = json_name(n);
		std::wstring w = std::wstring(s);
		_copyString(w, returnValue);
		json_free(s);
	}
	
	returnValue.setReturn(pResult);
}
void JSON_Parse_text(sLONG_PTR *pResult, PackagePtr pParams)
{
	C_TEXT source;
	C_TEXT returnValue;
	
	source.fromParamAtIndex(pParams, 1);
	
	std::wstring w;
	_copyString(source, w);
	
	if(json_is_valid(w.c_str())){
		JSONNODE *n = json_parse(w.c_str());
		_addJsonRootToList(n);
		_toHex(n, returnValue);
	}
	
	returnValue.setReturn(pResult);
}
void CrossPlatform::createDirectory(const std::string &path)
{
    char *dir = _copyString(path.c_str());

    try
    {
        for (char *dirDelim = strchr(dir, '/'); dirDelim != nullptr; dirDelim = strchr(dirDelim + 1, '/'))
        {
            *dirDelim = '\0';
            // Skip root directory
            if (dir != dirDelim) _createDirectory(dir);
            *dirDelim = '/';
        }
        _createDirectory(dir);
    }
    catch (const std::runtime_error &)
    {
        free(dir);
        throw;
    }

    free(dir);
}
void JSON_DELETE_ITEM_BY_NAME(sLONG_PTR *pResult, PackagePtr pParams)
{
	C_TEXT json;
	C_TEXT name;
	C_LONGINT option;
	
	json.fromParamAtIndex(pParams, 1);
	name.fromParamAtIndex(pParams, 2);
	option.fromParamAtIndex(pParams, 3);
	
	JSONNODE *n = _fromHex(json);
	
	if(n){
		std::wstring w;
		_copyString(name, w);
		
		JSONNODE_ITERATOR i;
		
		switch (option.getIntValue()) {
			case 1:
				i = json_find_nocase(n, w.c_str());
				break;
			default:
				i = json_find(n, w.c_str());
				break;
		}
		/*
		while (i != json_end(n)){
			json_erase(n, i);
			++i;	
		}
		 */
		if (i != json_end(n)){
			json_erase(n, i);	
		}
	}
}
void JSON_Append_long(sLONG_PTR *pResult, PackagePtr pParams)
{
	C_TEXT json;
	C_TEXT node;
	C_LONGINT value;
	C_TEXT returnValue;
	
	json.fromParamAtIndex(pParams, 1);
	node.fromParamAtIndex(pParams, 2);
	value.fromParamAtIndex(pParams, 3);
	
	JSONNODE *n = _fromHex(json);
	
	if(n){
		std::wstring nodeName;
		_copyString(node, nodeName);
		
		JSONNODE *_node = json_new_i(nodeName.c_str(), value.getIntValue());
		json_push_back(n, _node);
		_toHex(_node, returnValue);
	}
	
	returnValue.setReturn(pResult);
}
void JSON_GET_CHILD_NODES(sLONG_PTR *pResult, PackagePtr pParams)
{
	C_TEXT json;
	ARRAY_TEXT nodes;
	ARRAY_LONGINT types;
	ARRAY_TEXT names;
	
	json.fromParamAtIndex(pParams, 1);
	nodes.setSize(1);
	types.setSize(1);
	names.setSize(1);	
	
	JSONNODE *n = _fromHex(json);
	
	if(n){
		JSONNODE_ITERATOR i = json_begin(n);
		while (i != json_end(n)){
			if (*i){
				json_char *s = json_name(*i);
				std::wstring w = std::wstring(s);
				C_TEXT t;
				_copyString(w, t);
				json_free(s);
				CUTF16String nodeName;
				t.copyUTF16String(&nodeName);
				names.appendUTF16String(&nodeName);
				
				C_TEXT h;
				_toHex(*i, h);
				CUTF16String nodeRef;
				h.copyUTF16String(&nodeRef);	
				nodes.appendUTF16String(&nodeRef);				
				
				switch (json_type(*i)) {
					case JSON_NULL:
						types.appendIntValue(0);
						break;
					case JSON_STRING:
						types.appendIntValue(1);					
						break;
					case JSON_NUMBER:
						types.appendIntValue(2);							
						break;
					case JSON_BOOL:
						types.appendIntValue(3);							
						break;	
					case JSON_ARRAY:
						types.appendIntValue(4);							
						break;
					case JSON_NODE:
						types.appendIntValue(5);							
						break;							
				}
			}
			++i;			
		}
	}
	
	nodes.toParamAtIndex(pParams, 2);
	types.toParamAtIndex(pParams, 3);
	names.toParamAtIndex(pParams, 4);
}