@@ -1950,6 +1950,195 @@ TRI_json_t* TRI_ObjectToJson (v8::Isolate* isolate,
1950
1950
return json;
1951
1951
}
1952
1952
1953
+ // //////////////////////////////////////////////////////////////////////////////
1954
+ // / @brief convert a V8 value to a TRI_json_t value
1955
+ // //////////////////////////////////////////////////////////////////////////////
1956
+
1957
+ static int ObjectToJsonSimple (v8::Isolate* isolate,
1958
+ TRI_json_t* result,
1959
+ v8::Handle <v8::Value> const parameter) {
1960
+ v8::HandleScope scope (isolate);
1961
+
1962
+ if (parameter->IsNull ()) {
1963
+ TRI_InitNullJson (result);
1964
+ return TRI_ERROR_NO_ERROR;
1965
+ }
1966
+
1967
+ if (parameter->IsBoolean ()) {
1968
+ v8::Handle <v8::Boolean > booleanParameter = parameter->ToBoolean ();
1969
+ TRI_InitBooleanJson (result, booleanParameter->Value ());
1970
+ return TRI_ERROR_NO_ERROR;
1971
+ }
1972
+
1973
+ if (parameter->IsNumber ()) {
1974
+ v8::Handle <v8::Number> numberParameter = parameter->ToNumber ();
1975
+ TRI_InitNumberJson (result, numberParameter->Value ());
1976
+ return TRI_ERROR_NO_ERROR;
1977
+ }
1978
+
1979
+ if (parameter->IsString ()) {
1980
+ v8::Handle <v8::String> stringParameter = parameter->ToString ();
1981
+ TRI_Utf8ValueNFC str (TRI_UNKNOWN_MEM_ZONE, stringParameter);
1982
+
1983
+ if (*str == nullptr ) {
1984
+ TRI_InitNullJson (result);
1985
+ return TRI_ERROR_OUT_OF_MEMORY;
1986
+ }
1987
+
1988
+ // this passes ownership for the utf8 string to the JSON object
1989
+ TRI_InitStringJson (result, str.steal (), str.length ());
1990
+ return TRI_ERROR_NO_ERROR;
1991
+ }
1992
+
1993
+ if (parameter->IsArray ()) {
1994
+ v8::Handle <v8::Array> array = v8::Handle <v8::Array>::Cast (parameter);
1995
+ uint32_t const n = array->Length ();
1996
+
1997
+ // allocate the result array in one go
1998
+ TRI_InitArrayJson (TRI_UNKNOWN_MEM_ZONE, result, static_cast <size_t >(n));
1999
+ int res = TRI_ReserveVector (&result->_value ._objects , static_cast <size_t >(n));
2000
+
2001
+ if (res != TRI_ERROR_NO_ERROR) {
2002
+ // result array could not be allocated
2003
+ TRI_InitNullJson (result);
2004
+ return TRI_ERROR_OUT_OF_MEMORY;
2005
+ }
2006
+
2007
+ for (uint32_t i = 0 ; i < n; ++i) {
2008
+ // get address of next element
2009
+ TRI_json_t* next = static_cast <TRI_json_t*>(TRI_NextVector (&result->_value ._objects ));
2010
+ // the reserve call above made sure we could not have run out of memory
2011
+ TRI_ASSERT_EXPENSIVE (next != nullptr );
2012
+
2013
+ res = ObjectToJsonSimple (isolate, next, array->Get (i));
2014
+
2015
+ if (res != TRI_ERROR_NO_ERROR) {
2016
+ // to mimic behavior of previous ArangoDB versions, we need to silently ignore this error
2017
+ // now return the element to the vector
2018
+ TRI_ReturnVector (&result->_value ._objects );
2019
+
2020
+ // a better solution would be:
2021
+ // initialize the element at position, otherwise later cleanups may
2022
+ // peek into uninitialized memory
2023
+ // TRI_InitNullJson(next);
2024
+ // return res;
2025
+ }
2026
+ }
2027
+
2028
+ return TRI_ERROR_NO_ERROR;
2029
+ }
2030
+
2031
+ if (parameter->IsObject ()) {
2032
+ if (parameter->IsBooleanObject ()) {
2033
+ TRI_InitBooleanJson (result, v8::Handle <v8::BooleanObject>::Cast (parameter)->BooleanValue ());
2034
+ return TRI_ERROR_NO_ERROR;
2035
+ }
2036
+
2037
+ if (parameter->IsNumberObject ()) {
2038
+ TRI_InitNumberJson (result, v8::Handle <v8::NumberObject>::Cast (parameter)->NumberValue ());
2039
+ return TRI_ERROR_NO_ERROR;
2040
+ }
2041
+
2042
+ if (parameter->IsStringObject ()) {
2043
+ v8::Handle <v8::String> stringParameter (parameter->ToString ());
2044
+ TRI_Utf8ValueNFC str (TRI_UNKNOWN_MEM_ZONE, stringParameter);
2045
+
2046
+ if (*str == nullptr ) {
2047
+ TRI_InitNullJson (result);
2048
+ return TRI_ERROR_OUT_OF_MEMORY;
2049
+ }
2050
+
2051
+ // this passes ownership for the utf8 string to the JSON object
2052
+ TRI_InitStringJson (result, str.steal (), str.length ());
2053
+ return TRI_ERROR_NO_ERROR;
2054
+ }
2055
+
2056
+ v8::Handle <v8::Object> o = parameter->ToObject ();
2057
+ v8::Handle <v8::Array> names = o->GetOwnPropertyNames ();
2058
+ uint32_t const n = names->Length ();
2059
+
2060
+ // allocate the result object buffer in one go
2061
+ TRI_InitObjectJson (TRI_UNKNOWN_MEM_ZONE, result, static_cast <size_t >(n));
2062
+ int res = TRI_ReserveVector (&result->_value ._objects , static_cast <size_t >(n * 2 )); // key + value
2063
+
2064
+ if (res != TRI_ERROR_NO_ERROR) {
2065
+ // result object buffer could not be allocated
2066
+ TRI_InitNullJson (result);
2067
+ return TRI_ERROR_OUT_OF_MEMORY;
2068
+ }
2069
+
2070
+ for (uint32_t i = 0 ; i < n; ++i) {
2071
+ // process attribute name
2072
+ v8::Handle <v8::Value> key = names->Get (i);
2073
+ TRI_Utf8ValueNFC str (TRI_UNKNOWN_MEM_ZONE, key);
2074
+
2075
+ if (*str == nullptr ) {
2076
+ return TRI_ERROR_OUT_OF_MEMORY;
2077
+ }
2078
+
2079
+ TRI_json_t* next = static_cast <TRI_json_t*>(TRI_NextVector (&result->_value ._objects ));
2080
+ // the reserve call above made sure we could not have run out of memory
2081
+ TRI_ASSERT_EXPENSIVE (next != nullptr );
2082
+
2083
+ // this passes ownership for the utf8 string to the JSON object
2084
+ char * attributeName = str.steal ();
2085
+ TRI_InitStringJson (next, attributeName, str.length ());
2086
+
2087
+ // process attribute value
2088
+ next = static_cast <TRI_json_t*>(TRI_NextVector (&result->_value ._objects ));
2089
+ // the reserve call above made sure we could not have run out of memory
2090
+ TRI_ASSERT_EXPENSIVE (next != nullptr );
2091
+
2092
+ res = ObjectToJsonSimple (isolate, next, o->Get (key));
10000
2093
+
2094
+ if (res != TRI_ERROR_NO_ERROR) {
2095
+ // to mimic behavior of previous ArangoDB versions, we need to silently ignore this error
2096
+ // now free the attributeName string and return the elements to the vector
2097
+ TRI_FreeString (TRI_UNKNOWN_MEM_ZONE, attributeName);
2098
+ TRI_ReturnVector (&result->_value ._objects );
2099
+ TRI_ReturnVector (&result->_value ._objects );
2100
+
2101
+ // a better solution would be:
2102
+ // initialize the element at position, otherwise later cleanups may
2103
+ // peek into uninitialized memory
2104
+ // TRI_InitNullJson(next);
2105
+ // return res;
2106
+ }
2107
+ }
2108
+
2109
+ return TRI_ERROR_NO_ERROR;
2110
+ }
2111
+
2112
+ TRI_InitNullJson (result);
2113
+ return TRI_ERROR_BAD_PARAMETER;
2114
+ }
2115
+
2116
+ // //////////////////////////////////////////////////////////////////////////////
2117
+ // / @brief convert a V8 value to a json_t value
2118
+ // / this function assumes that the V8 object does not contain any cycles and
2119
+ // / does not contain types such as Function, Date or RegExp
2120
+ // //////////////////////////////////////////////////////////////////////////////
2121
+
2122
+ TRI_json_t* TRI_ObjectToJsonSimple (v8::Isolate* isolate,
2123
+ v8::Handle <v8::Value> const parameter) {
2124
+
2125
+ TRI_json_t* json = TRI_CreateNullJson (TRI_UNKNOWN_MEM_ZONE);
2126
+
2127
+ if (json == nullptr ) {
2128
+ return nullptr ;
2129
+ }
2130
+
2131
+ int res = ObjectToJsonSimple (isolate, json, parameter);
2132
+
2133
+ if (res != TRI_ERROR_NO_ERROR) {
2134
+ // some processing error occurred
2135
+ TRI_FreeJson (TRI_UNKNOWN_MEM_ZONE, json);
2136
+ return nullptr ;
2137
+ }
2138
+
2139
+ return json;
2140
+ }
2141
+
1953
2142
// //////////////////////////////////////////////////////////////////////////////
1954
2143
// / @brief converts a V8 object to a string
1955
2144
// //////////////////////////////////////////////////////////////////////////////
0 commit comments