Beispiel #1
0
ArvZip *
arv_zip_new (const void *buffer, size_t size)
{
        ArvZip *zip;
        const void *ptr;
        int i;
	gboolean directory_found;

	g_return_val_if_fail (buffer != NULL, NULL);
	g_return_val_if_fail (size > 0, NULL);

        zip = g_new0 (ArvZip, 1);
	zip->buffer = buffer;
	zip->buffer_size = size;

	directory_found = FALSE;
        for (i = zip->buffer_size - 4; i > 0; i--) {
                if (zip->buffer[i] == 0x50 &&
		    zip->buffer[i+1] == 0x4b &&
		    zip->buffer[i+2] == 0x05 &&
		    zip->buffer[i+3] == 0x06) {
			zip->directory_position = i;
			directory_found = TRUE;
                        break;
                }
        }
	if (!directory_found) {
		arv_debug_misc ("[Zip::new] Magic number for end of central directory not found (0x06054b50)");
		return zip;
	}

	ptr = zip->buffer + zip->directory_position;
        zip->n_files = ARV_GUINT16_FROM_LE_PTR (ptr, 10);
        if (ARV_GUINT16_FROM_LE_PTR (ptr, 8) != zip->n_files) {
		arv_debug_misc ("[Zip::new] Mismatch in number of files");
		zip->n_files = 0;
		return zip;
        }

        zip->directory_size = ARV_GUINT32_FROM_LE_PTR (ptr, 12);
        zip->directory_offset = ARV_GUINT32_FROM_LE_PTR (ptr, 16);
        zip->header_size = zip->directory_position - (zip->directory_offset + zip->directory_size);

	arv_log_misc ("[Zip::new] number of files = %d", zip->n_files);
	arv_log_misc ("[Zip::new] directory position = 0x%08x", zip->directory_position);
	arv_log_misc ("[Zip::new] directory size = %d", zip->directory_size);
	arv_log_misc ("[Zip::new] directory offset = 0x%08x", zip->directory_offset);
	arv_log_misc ("[Zip::new] header size = %d", zip->header_size);

        arv_zip_build_file_list (zip);

        return zip;
}
Beispiel #2
0
static void
arv_zip_build_file_list (ArvZip *zip)
{
        ArvZipFile *zip_file;
        const void *ptr;
        ptrdiff_t offset;
        guint i;

        offset = zip->directory_offset;

	for (i = 0; i < zip->n_files; i++) {
		ptr = zip->buffer + zip->header_size + offset;
		if (ARV_GUINT32_FROM_LE_PTR (ptr, 0) != 0x02014b50) {
			arv_debug_misc ("[Zip::build_file_list] Magic number of central directory not found (0x02014b50)");
			arv_debug_misc ("[Zip::build_file_list] Expected at 0x%08x - found 0x%08x instead",
					zip->header_size + offset, ARV_GUINT32_FROM_LE_PTR (ptr, 0));
		       	return;
		}

		zip_file = g_new0 (ArvZipFile, 1);
                zip_file->compressed_size = ARV_GUINT32_FROM_LE_PTR (ptr, 20);
                zip_file->uncompressed_size = ARV_GUINT32_FROM_LE_PTR (ptr, 24);
                zip_file->offset = ARV_GUINT32_FROM_LE_PTR (ptr, 42);
		zip_file->name = g_strndup (((char *) ptr) + 46, ARV_GUINT16_FROM_LE_PTR (ptr, 28));

		arv_log_misc ("[Zip::list_files] %s", zip_file->name);

		zip->files = g_slist_prepend (zip->files, zip_file);

                offset += 0x2e +
			ARV_GUINT16_FROM_LE_PTR (ptr, 28) + /* filename size */
			ARV_GUINT16_FROM_LE_PTR (ptr, 30) + /* extra field */
			ARV_GUINT16_FROM_LE_PTR (ptr, 32);  /* file comment */
	}
}
Beispiel #3
0
static char *
_load_genicam (ArvGvDevice *gv_device, guint32 address, size_t  *size)
{
	char filename[ARV_GVBS_XML_URL_SIZE];
	char **tokens;
	char *genicam = NULL;

	g_return_val_if_fail (size != NULL, NULL);

	*size = 0;

	if (!arv_device_read_memory (ARV_DEVICE (gv_device), address, ARV_GVBS_XML_URL_SIZE, filename, NULL))
		return NULL;

	filename[ARV_GVBS_XML_URL_SIZE - 1] = '\0';

	arv_debug_device ("[GvDevice::load_genicam] xml url = '%s' at 0x%x", filename, address);

	tokens = g_regex_split (arv_gv_device_get_url_regex (), filename, 0);

	if (tokens[0] != NULL) {
		if (g_strcmp0 (tokens[1], "File:") == 0)
			g_file_get_contents (filename, &genicam, NULL, NULL);
		else if (g_strcmp0 (tokens[1], "Local:") == 0 &&
			 tokens[2] != NULL &&
			 tokens[3] != NULL &&
			 tokens[4] != NULL) {
			guint32 file_address;
			guint32 file_size;

			file_address = strtoul (tokens[3], NULL, 16);
			file_size = strtoul (tokens[4], NULL, 16);

			arv_debug_device ("[GvDevice::load_genicam] Xml address = 0x%x - size = 0x%x - %s",
					  file_address, file_size, tokens[2]);

			if (file_size > 0) {
				genicam = g_malloc (file_size);
				if (arv_device_read_memory (ARV_DEVICE (gv_device), file_address, file_size,
							    genicam, NULL)) {

					if (arv_debug_check (&arv_debug_category_misc, ARV_DEBUG_LEVEL_LOG)) {
						GString *string = g_string_new ("");
						
						g_string_append_printf (string,
									"[GvDevice::load_genicam] Raw data size = 0x%x\n", file_size);
						arv_g_string_append_hex_dump (string, genicam, file_size);

						arv_log_misc ("%s", string->str);

						g_string_free (string, TRUE);
					}

					if (g_str_has_suffix (tokens[2], ".zip")) {
						ArvZip *zip;
						const GSList *zip_files;

						arv_debug_device ("[GvDevice::load_genicam] Zipped xml data");

						zip = arv_zip_new (genicam, file_size);
						zip_files = arv_zip_get_file_list (zip);

						if (zip_files != NULL) {
							const char *zip_filename;
							void *tmp_buffer;
							size_t tmp_buffer_size;

							zip_filename = arv_zip_file_get_name (zip_files->data);
							tmp_buffer = arv_zip_get_file (zip, zip_filename,
										       &tmp_buffer_size);

							g_free (genicam);
							file_size = tmp_buffer_size;
							genicam = tmp_buffer;
						} else
							arv_warning_device ("[GvDevice::load_genicam] Invalid format");
						arv_zip_free (zip);
					}
					*size = file_size;
				} else {
					g_free (genicam);
					genicam = NULL;
					*size = 0;
				}
			}
		}
	}

	g_strfreev (tokens);

	return genicam;
}