/// <summary> /// Adds items of "array" to "result" merging those whose string keys are the same. /// </summary> private static bool MergeRecursiveInternal(PhpArray/*!*/ result, PhpArray/*!*/ array, bool deepCopy) { foreach (KeyValuePair<IntStringKey, object> entry in array) { if (entry.Key.IsString) { if (result.ContainsKey(entry.Key)) { // the result array already contains the item => merging take place object xv = result[entry.Key]; object yv = entry.Value; // source item: object x = PhpVariable.Dereference(xv); object y = PhpVariable.Dereference(yv); PhpArray ax = x as PhpArray; PhpArray ay = y as PhpArray; // if x is not a reference then we can reuse the ax array for the result // since it has been deeply copied when added to the resulting array: PhpArray item_result = (deepCopy && x == xv && ax != null) ? ax : new PhpArray(); if (ax != null && ay != null) { if (ax != item_result) ax.AddTo(item_result, deepCopy); if (ax.Visited && ay.Visited) return false; ax.Visited = true; ay.Visited = true; // merges ay to the item result (may lead to stack overflow, // but only with both arrays recursively referencing themselves - who cares?): bool finite = MergeRecursiveInternal(item_result, ay, deepCopy); ax.Visited = false; ay.Visited = false; if (!finite) return false; } else { if (ax != null) { if (ax != item_result) ax.AddTo(item_result, deepCopy); } else { /*if (x != null)*/ item_result.Add((deepCopy) ? PhpVariable.DeepCopy(x) : x); } if (ay != null) ay.AddTo(item_result, deepCopy); else /*if (y != null)*/ item_result.Add((deepCopy) ? PhpVariable.DeepCopy(y) : y); } result[entry.Key] = item_result; } else { // PHP does no dereferencing when items are not merged: result.Add(entry.Key, (deepCopy) ? PhpVariable.DeepCopy(entry.Value) : entry.Value); } } else { // PHP does no dereferencing when items are not merged: result.Add((deepCopy) ? PhpVariable.DeepCopy(entry.Value) : entry.Value); } } return true; }
public static bool KeyExists(object key, PhpArray array) { if (array == null) { PhpException.ArgumentNull("array"); return false; } IntStringKey array_key; if (Core.Convert.ObjectToArrayKey(key, out array_key)) return array.ContainsKey(array_key); PhpException.Throw(PhpError.Warning, CoreResources.GetString("illegal_offset_type")); return false; }
public static PhpArray FillKeys(PhpArray keys, object value) { if (keys == null) { PhpException.ArgumentNull("keys"); return null; } var result = new PhpArray(keys.Count); foreach (var x in keys) { IntStringKey key; if (Core.Convert.ObjectToArrayKey(x.Value, out key) && !result.ContainsKey(key)) { result.Add(key, value); } } // makes deep copies of all added items: result.InplaceCopyOnReturn = true; return result; }
private void UpdateValueAndIndexArrays(ElementRecord elementRecord, ref TextRecord textRecord, PhpArray values, PhpArray indices, bool middle) { // if we have no valid data in the middle, just end if (middle && textRecord == null) return; if (!middle && elementRecord.State == ElementState.Interior) UpdateValueAndIndexArrays(elementRecord, ref textRecord, values, indices, true); if (values != null) { PhpArray arrayRecord = new PhpArray(); arrayRecord.Add("tag", elementRecord.ElementName); arrayRecord.Add("level", elementRecord.Level); if (elementRecord.State == ElementState.Beginning) arrayRecord.Add("type", middle ? "open" : "complete"); else arrayRecord.Add("type", middle ? "cdata" : "close"); if (textRecord != null) arrayRecord.Add("value", textRecord.Text); if (elementRecord.State == ElementState.Beginning && elementRecord.Attributes.Count != 0) arrayRecord.Add("attributes", elementRecord.Attributes); values.Add(arrayRecord); if (indices != null) { PhpArray elementIndices; if (!indices.ContainsKey(elementRecord.ElementName)) { elementIndices = new PhpArray(); indices.Add(elementRecord.ElementName, elementIndices); } else elementIndices = (PhpArray)indices[elementRecord.ElementName]; // add the max index (last inserted value) elementIndices.Add(values.MaxIntegerKey); } } textRecord = null; }
public static PhpArray FillKeys(PhpArray keys, object value) { PhpArray result = new PhpArray(keys.Count); if (keys != null) foreach (var x in keys) { IntStringKey key; if (!PHP.Core.Convert.ObjectToArrayKey(x.Value, out key)) continue; if (!result.ContainsKey(key)) result.Add(key, value); } // makes deep copies of all added items: result.InplaceCopyOnReturn = true; return result; }
/// <summary> /// Loads $_SERVER from HttpRequest.ServerVariables. /// </summary> private void InitializeServerVariables(LocalConfiguration/*!*/ config, HttpContext context) { if (context == null) { Server.Value = new PhpArray(); return; } Debug.Assert(config != null); PhpArray array, argv; var request = context.Request; var serverVariables = request.ServerVariables; Server.Value = array = new PhpArray(0, /*serverVariables.Count*/64); // adds variables defined by ASP.NET and IIS: LoadFromCollection(array, serverVariables); // adds argv, argc variables: if (Configuration.Global.GlobalVariables.RegisterArgcArgv) { array["argv"] = argv = new PhpArray(1) { request.QueryString }; array["argc"] = 0; } // additional variables defined in PHP manual: array["PHP_SELF"] = request.Path; try { array["DOCUMENT_ROOT"] = request.MapPath("/"); // throws exception under mod_aspdotnet } catch { array["DOCUMENT_ROOT"] = null; } array["SERVER_ADDR"] = serverVariables["LOCAL_ADDR"]; array["REQUEST_URI"] = request.RawUrl; array["REQUEST_TIME"] = DateTimeUtils.UtcToUnixTimeStamp(context.Timestamp.ToUniversalTime()); array["SCRIPT_FILENAME"] = request.PhysicalPath; //IPv6 is the default in IIS7, convert to an IPv4 address (store the IPv6 as well) if (request.UserHostAddress.Contains(":")) { array["REMOTE_ADDR_IPV6"] = request.UserHostAddress; if (request.UserHostAddress == "::1") { array["REMOTE_ADDR"] = array["SERVER_ADDR"] = "127.0.0.1"; } else foreach (IPAddress IPA in Dns.GetHostAddresses(request.UserHostAddress)) { if (IPA.AddressFamily.ToString() == "InterNetwork") { array["REMOTE_ADDR"] = IPA.ToString(); break; } } } // PATH_INFO // should contain partial path information only // note: IIS has AllowPathInfoForScriptMappings property that do the thing ... but ISAPI does not work then // hence it must be done here manually if (array.ContainsKey("PATH_INFO")) { string path_info = (string)array["PATH_INFO"]; string script_name = (string)array["SCRIPT_NAME"]; // 'ORIG_PATH_INFO' // Original version of 'PATH_INFO' before processed by PHP. array["ORIG_PATH_INFO"] = path_info; // 'PHP_INFO' // Contains any client-provided pathname information trailing the actual script filename // but preceding the query string, if available. For instance, if the current script was // accessed via the URL http://www.example.com/php/path_info.php/some/stuff?foo=bar, // then $_SERVER['PATH_INFO'] would contain /some/stuff. // php-5.3.2\sapi\isapi\php5isapi.c: // // strncpy(path_info_buf, static_variable_buf + scriptname_len - 1, sizeof(path_info_buf) - 1); // PATH_INFO = PATH_INFO.SubString(SCRIPT_NAME.Length); array["PATH_INFO"] = (script_name.Length <= path_info.Length) ? path_info.Substring(script_name.Length) : string.Empty; } }
private object BindArray(PhpArray array, Type targetType) { if (targetType.IsArray) { array = (PhpArray) (array.ContainsKey("item") ? array["item"] : array); // TODO: ??? return BindArrayToArray(array, targetType); } else return BindArrayToObject(array, targetType); }