void run(fiftyoneDegreesProvider* provider, char* properties[],
         int propertiesCount, const char *inputFile) {
	char userAgent[1000];
	const char* value;
	int i, j;
	fiftyoneDegreesWorkset *ws = NULL;

	// Get a workset from the pool to perform this match.
	ws = fiftyoneDegreesProviderWorksetGet(provider);

	printf("Starting Offline Processing Example.\n");

	// Opens input and output files.
	char* outputFile = "offlineProcessingOutput.csv";
	FILE* fin = fopen(inputFile, "r");
	FILE* fout = fopen(outputFile, "w");

	// Print CSV headers to output file.
	fprintf(fout, "User-Agent");
	for (j=0;j<propertiesCount;j++) {
		fprintf(fout, "|%s", properties[j]);
	}
	fprintf(fout, "\n");

	// Carries out match for first 20 User-Agents and prints results to
	// output file.
	for (i=0;i<20;i++) {
		fgets(userAgent, sizeof(userAgent), fin);
		userAgent[strlen(userAgent)-1] = '\0';
		fprintf(fout, "%s", userAgent);
		fiftyoneDegreesMatch(ws, userAgent);
		for (j=0;j<propertiesCount;j++) {
			value = getValue(ws, properties[j]);
			fprintf(fout, "|%s", value);
		}
		fprintf(fout, "\n");
	}

	printf("Output Written to %s\n", outputFile);

	// Release workset after match complete and workset no longer required.
	fiftyoneDegreesWorksetRelease(ws);
}
Exemplo n.º 2
0
/**
* Demonstrates the dataset, pool and cache reload functionality in a multi
* threaded environment. When a workset is returned to the pool of worksets
* a check is carried out to see if the pool is now inactive and all of the
* worksets have been returned. If both conditions are met the pool is
* freed along with the underlying dataset and cache.
*
* @param inputFile containing HTTP User-Agent strings.
*/
static void runRequests(void* inputFile) {
	fiftyoneDegreesWorkset *ws = NULL;
	unsigned long hashCode = 0;
	char userAgent[1000];
	FILE* fin = fopen((const char*)inputFile, "r");

	while (fgets(userAgent, sizeof(userAgent), fin) != NULL) {
		ws = fiftyoneDegreesProviderWorksetGet(&provider);
		fiftyoneDegreesMatch(ws, userAgent);
		hashCode ^= getHashCode(ws);
		fiftyoneDegreesWorksetRelease(ws);
	}

	fclose(fin);
	printf("Finished with hashcode '%lu'\r\n", hashCode);
	FIFTYONEDEGREES_MUTEX_LOCK(&lock);
	threadsFinished++;
	FIFTYONEDEGREES_MUTEX_UNLOCK(&lock);
}
Exemplo n.º 3
0
/**
* Demonstrates the dataset, pool and cache reload functionality in a single
* threaded environment. Since only one thread is available the reload will
* be done as part of the program flow and detection will not be available for
* the very short time that the dataset, pool and cache are being reloaded.
*
* The reload happens every 500 requests. The total number of dataset reloads
* is then returned.
*
* @param inputFile containing HTTP User-Agent strings to use with device
*		  detection.
* @return number of times the dataset, pool and cache were reloaded.
*/
static int runRequest(const char *inputFile) {
	fiftyoneDegreesWorkset *ws = NULL;
	unsigned long hashCode = 0;
	int count = 0, numberOfReloads = 0;
	char userAgent[1000];
	char *fileInMemory;
	char *pathToFileInMemory;
	long currentFileSize;
	FILE* fin = fopen((const char*)inputFile, "r");
	// In this example the same data file is reloaded from.
	// Store path for use with reloads.
	pathToFileInMemory = (char*)malloc(sizeof(char) *
						(strlen(provider.activePool->dataSet->fileName) + 1));
	memcpy(pathToFileInMemory,
		provider.activePool->dataSet->fileName,
		strlen(provider.activePool->dataSet->fileName) + 1);

	while (fgets(userAgent, sizeof(userAgent), fin) != NULL) {
		ws = fiftyoneDegreesProviderWorksetGet(&provider);
		fiftyoneDegreesMatch(ws, userAgent);
		hashCode ^= getHashCode(ws);
		fiftyoneDegreesWorksetRelease(ws);
		count++;

		if (count % 1000 == 0) {
			// Load file into memory.
			currentFileSize = loadFile(pathToFileInMemory, &fileInMemory);
			// Refresh the current dataset.
			fiftyoneDegreesProviderReloadFromMemory(&provider, (void*)fileInMemory, currentFileSize);

			fiftyoneDegreesDataSet *ds = (fiftyoneDegreesDataSet*)provider.activePool->dataSet;
			// Tell the API to free the memory occupied by the data file.
			ds->memoryToFree = (void*)fileInMemory;
			numberOfReloads++;
		}
	}

	fclose(fin);
	free(pathToFileInMemory);
	printf("Finished with hashcode '%lu'\r\n", hashCode);
	return numberOfReloads;
}
Exemplo n.º 4
0
// Execute a performance test using a file of null terminated useragent strings
// as input. If calibrate is true then the file is read but no detections
// are performed.
void runPerformanceTest(PERFORMANCE_STATE *state) {
	char *input = (char*)malloc(state->pool->dataSet->header.maxUserAgentLength + 1);
	char *result = NULL;
	long valueCount;
	FILE *inputFilePtr;
	int i, v, count = 0;
	fiftyoneDegreesWorkset *ws = NULL;

    // Open the file and check it's valid.
    inputFilePtr = fopen(state->fileName, "r");
	if (inputFilePtr == NULL) {
        printf("Failed to open file with null-terminating user agent strings to fiftyoneDegreesMatch against 51Degrees data file. \n");
        fclose(inputFilePtr);
        exit(0);
	}

    // Get the first entry from the file.
    result = fgets(input, state->pool->dataSet->header.maxUserAgentLength, inputFilePtr);

	while(result != NULL && !feof(inputFilePtr)) {

        // Split the string at carriage returns.
		strtok(result, "\n");

		// If detection should be performed get the result and the property values.
		if (state->calibrate == 0) {
            ws = fiftyoneDegreesWorksetPoolGet(state->pool);
			fiftyoneDegreesMatch(ws, input);
			valueCount = 0;
			for (i = 0; i < ws->dataSet->requiredPropertyCount; i++) {
				fiftyoneDegreesSetValues(ws, i);
				for (v = 0; v < ws->valuesCount; v++) {
					valueCount += (long)(ws->values[v]->nameOffset);
				}
			}
			fiftyoneDegreesWorksetPoolRelease(state->pool, ws);
#ifndef FIFTYONEDEGREES_NO_THREADING
			FIFTYONEDEGREES_MUTEX_LOCK(&state->lock);
#endif
			state->valueCount += valueCount;
#ifndef FIFTYONEDEGREES_NO_THREADING
			FIFTYONEDEGREES_MUTEX_UNLOCK(&state->lock);
#endif
		}

		count++;

		// Print a progress marker.
		if (count == state->progress) {
			reportProgress(state, count);
			count = 0;
		}

		// Get the next entry from the data file.
		result = fgets(input, state->pool->dataSet->header.maxUserAgentLength, inputFilePtr);
    }

    free(input);

	reportProgress(state, count);
	fclose(inputFilePtr);

#ifndef FIFTYONEDEGREES_NO_THREADING
	FIFTYONEDEGREES_THREAD_EXIT;
#endif
}
Exemplo n.º 5
0
int main(int argc, char* argv[]) {
	fiftyoneDegreesWorkset *ws = NULL;
	fiftyoneDegreesDataSet dataSet;
    char *output;
	char *fileName = argc > 1 ? argv[1] : "../../../data/51Degrees-LiteV3.2.dat";
	char *requiredProperties = argc > 2 ? argv[2] : NULL;
	char *result;

	switch (fiftyoneDegreesInitWithPropertyString(fileName, &dataSet, requiredProperties)) {
	case DATA_SET_INIT_STATUS_INSUFFICIENT_MEMORY:
		printf("Insufficient memory to load '%s'.", argv[1]);
		break;
	case DATA_SET_INIT_STATUS_POINTER_OUT_OF_BOUNDS:
	case DATA_SET_INIT_STATUS_CORRUPT_DATA:
		printf("Device data file '%s' is corrupted.", argv[1]);
		break;
	case DATA_SET_INIT_STATUS_INCORRECT_VERSION:
		printf("Device data file '%s' is not correct version.", argv[1]);
		break;
	case DATA_SET_INIT_STATUS_FILE_NOT_FOUND:
		printf("Device data file '%s' not found.", argv[1]);
		break;
	case DATA_SET_INIT_STATUS_NULL_POINTER:
		printf("Null pointer prevented loading of '%s'.", argv[1]);
		break;
	default: {

		ws = fiftyoneDegreesWorksetCreate(&dataSet, NULL);
		output = fiftyoneDegreesCSVCreate(ws);

#ifdef _MSC_VER
		result = gets_s(ws->input, dataSet.header.maxUserAgentLength);
#else
		result = fgets(ws->input, ws->dataSet->header.maxUserAgentLength, stdin);
#endif
		while (result != NULL) {
			fiftyoneDegreesMatch(ws, ws->input);
			if (ws->profileCount > 0) {
				fiftyoneDegreesProcessDeviceCSV(ws, output);
				printf("%s", output);
				/* Diagnostics Info
				printf("\r\nDiagnostics Information\r\n\r\n");
				printf("  Difference:           %i\r\n", ws->difference);
				printf("  Method:               %i\r\n", ws->method);
				printf("  Root Nodes Evaluated: %i\r\n", ws->rootNodesEvaluated);
				printf("  Nodes Evaluated:      %i\r\n", ws->nodesEvaluated);
				printf("  Strings Read:         %i\r\n", ws->stringsRead);
				printf("  Signatures Read:      %i\r\n", ws->signaturesRead);
				printf("  Signatures Compared:  %i\r\n", ws->signaturesCompared);
				printf("  Closest Signatures:   %i\r\n", ws->closestSignatures);
				*/
			}
			else {
				printf("null\n");
			}

			// Flush buffers.
			fflush(stdin);
			fflush(stdout);

			// Get the next useragent.
#ifdef _MSC_VER
			gets_s(ws->input, dataSet.header.maxUserAgentLength);
#else
			result = fgets(ws->input, ws->dataSet->header.maxUserAgentLength, stdin);
#endif
		}

        fiftyoneDegreesCSVFree(output);
		fiftyoneDegreesWorksetFree(ws);
		fiftyoneDegreesDataSetFree(&dataSet);
	}//End default
		break;
	}//End Switch

	return 0;
}
/**
 * Internal function that performs match with a single User-Agent HTTP header
 * string and invokes the buildArray function to process the results.
 * @param userAgent is the User-Agent string to be matched.
 * @param userAgentLength is the length of the User-Agent string.
 * @param returnArray a pointer to the Zend array to store results in.
 */
void matchUserAgent(char *userAgent, int userAgentLength, zval *returnArray) {
    // Match the provided user agent.
    fiftyoneDegreesMatch(FIFTYONE_G(ws), userAgent);
    // Build the PHP array with the result.
    buildArray(returnArray);
}