private static Results MatchMultiProcessor(string userAgent, Handler handler) { // Provide an object to signal when the request has completed. AutoResetEvent waiter = new AutoResetEvent(false); // Create the request. Request request = new Request(userAgent, handler, waiter); if (request.Count > 0) { // For each thread add this to the queue. for (int i = 0; i < Environment.ProcessorCount; i++) ThreadPool.QueueUserWorkItem(ServiceRequest, request); // Wait until a signal is received. Keeping coming back to // this thread so that a request to close the request // can be processed. while (waiter.WaitOne(1, false) == false) { // Do nothing } ; } // Return the results. return request.Results; }
internal Request(string userAgent, Handler handler, AutoResetEvent completeEvent) { _userAgent = userAgent; _queue = CreateQueue(handler); _handler = handler; _completeEvent = completeEvent; }
private static Results MatchSingleProcessor(string userAgent, Handler handler) { // Create a single matcher and start it. Request request = new Request(userAgent, handler); // Process the request. ServiceRequest(request); // Return the results. return request.Results; }
/// <summary> /// Returns the closest match to the userAgent string from the queue of /// possible values. /// </summary> /// <param name="userAgent">userAgent being matched</param> /// <param name="handler">the handler associated with the matching request</param> /// <returns>best match userAgent</returns> internal static Results Match(string userAgent, Handler handler) { if (Environment.ProcessorCount > 1 && Detection.Constants.ForceSingleProcessor == false) { return MatchMultiProcessor(userAgent, handler); } else { return MatchSingleProcessor(userAgent, handler); } }
/// <summary> /// Uses a reduced initial string matching routine to determine the results. /// </summary> /// <param name="userAgent">The useragent to be matched.</param> /// <param name="handler">The handler performing the match.</param> /// <param name="tolerance">The number of characters that need to be the same at the begining of the string for a match to have occurred.</param> /// <returns>All the devices that matched.</returns> internal static Results Match(string userAgent, Handler handler, int tolerance) { DeviceInfo bestMatch = null; int maxInitialString = 0; lock (handler.UserAgents) { #if VER4 foreach (DeviceInfo device in handler.UserAgents.SelectMany(devices => devices)) { Check(userAgent, ref bestMatch, ref maxInitialString, device); } #elif VER2 foreach (var devices in handler.UserAgents) { foreach (DeviceInfo device in devices) { Check(userAgent, ref bestMatch, ref maxInitialString, device); } } #endif } return maxInitialString >= tolerance ? new Results(bestMatch) : null; }
/// <summary> /// Adds the handler to the list of handlers if the handler's confidence /// is higher than or equal to the current highest handler confidence. /// </summary> /// <param name="highestConfidence">Highest confidence value to far.</param> /// <param name="handlers">List of handlers.</param> /// <param name="handler">Handler to be considered for adding.</param> /// <returns>The new highest confidence value.</returns> private static void GetHandlers(ref byte highestConfidence, List<Handler> handlers, Handler handler) { if (handler.Confidence > highestConfidence) { handlers.Clear(); handlers.Add(handler); highestConfidence = handler.Confidence; } else if (handler.Confidence == highestConfidence) handlers.Add(handler); }
/// <summary> /// Use the HttpRequest fields to determine the closest matching device /// from the handlers provided. /// </summary> /// <param name="request">HttpRequest object.</param> /// <param name="handlers">Handlers capable of finding devices for the request.</param> /// <returns>The closest matching device or null if one can't be found.</returns> private static DeviceInfo GetDeviceInfo(HttpRequest request, Handler[] handlers) { DeviceInfo device = null; Results results = new Results(); #if VER4 foreach (Results temp in handlers.Select(t => t.Match(request)).Where(temp => temp != null)) { results.AddRange(temp); } #elif VER2 for (int i = 0; i < handlers.Length; i++) { // Find the closest matching devices. Results temp = handlers[i].Match(request); // If some results have been found. if (temp != null) // Combine the results with results from previous // handlers. results.AddRange(temp); } #endif if (results.Count == 1) { // Use the only result provided. device = results[0].Device; } else if (results.Count > 1) { // Uses the matcher to narrow down the results. device = Matcher.Match(GetUserAgent(request), results); } if (device == null) // No device was found so use the default device for the first // handler provided. device = handlers[0].DefaultDevice; return device; }
internal Request(string userAgent, Handler handler) { _userAgent = userAgent; _queue = CreateQueue(handler); _handler = handler; }
/// <summary> /// Takes a handler and returns a queue containing the userAgent strings. Ensures a /// lock is obtained on the handler before creating the queue to avoid another thread /// accessing or changing content at the same time. /// </summary> /// <param name="handler">handler containing devices</param> /// <returns>queue of userAgent strings</returns> private static Queue<DeviceInfo> CreateQueue(Handler handler) { Queue<DeviceInfo> queue = new Queue<DeviceInfo>(handler.UserAgents.Count); lock (handler.UserAgents) { foreach (var devices in handler.UserAgents) { foreach (DeviceInfo device in devices) { queue.Enqueue(device); } } } return queue; }
internal Request(string userAgent, Handler handler, AutoResetEvent completeEvent) : base(userAgent, handler, completeEvent) { _results = new Results(); }
internal Request(string userAgent, Handler handler) : base(userAgent, handler) { _results = new Results(); }