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) { BaseDeviceInfo bestMatch = null; int maxInitialString = 0; lock (handler.Devices) { foreach (var devices in handler.Devices.Values) { foreach (BaseDeviceInfo device in devices) { Check(userAgent, ref bestMatch, ref maxInitialString, device); } } } 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> /// Processes the current handler and adds it to the list of handlers. /// </summary> /// <param name="handlers">The list of all handers to be added to.</param> /// <param name="handler">The current handler object.</param> /// <param name="reader">The XML stream reader.</param> private static void ProcessHandler(List<Handler> handlers, Handler handler, XmlReader reader) { while (reader.Read()) { if (reader.Depth > 0 && reader.IsStartElement()) { switch (reader.Name) { case "canHandle": handler.CanHandleRegex.AddRange(ProcessRegex(reader.ReadSubtree())); break; case "cantHandle": handler.CantHandleRegex.AddRange(ProcessRegex(reader.ReadSubtree())); break; case "regexSegments": if (handler is RegexSegmentHandler) ProcessRegexSegments((RegexSegmentHandler)handler, reader.ReadSubtree()); break; } } } handlers.Add(handler); }
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>A queue of devices.</returns> private static Queue<BaseDeviceInfo> CreateQueue(Handler handler) { Queue<BaseDeviceInfo> queue = new Queue<BaseDeviceInfo>(handler.Devices.Count); lock (handler.Devices) { foreach (var devices in handler.Devices.Values) { foreach (BaseDeviceInfo 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(); }