summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2012-05-23 22:51:18 +0000
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2012-05-23 22:51:18 +0000
commita29fd7ddb5d63688a4d44d08e4ab16428921c321 (patch)
treed8e716c51da91f08d468e90262417f9a6d6fd5b0 /examples
parentf3c17241a42a0845eae2099e6970b5aca9bbd836 (diff)
downloadcups-a29fd7ddb5d63688a4d44d08e4ab16428921c321.tar.gz
Merge changes from CUPS 1.6svn-r10510.
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@3833 a1ca3aef-8c08-0410-bb20-df032aa958be
Diffstat (limited to 'examples')
-rw-r--r--examples/ppdx.c314
-rw-r--r--examples/ppdx.h82
-rw-r--r--examples/testppdx.c117
-rw-r--r--examples/testppdx.ppd121
4 files changed, 634 insertions, 0 deletions
diff --git a/examples/ppdx.c b/examples/ppdx.c
new file mode 100644
index 000000000..61588cad1
--- /dev/null
+++ b/examples/ppdx.c
@@ -0,0 +1,314 @@
+/*
+ * "$Id$"
+ *
+ * Example code for encoding and decoding large amounts of data in a PPD file.
+ * This would typically be used in a driver to save configuration/state
+ * information that could be used by an application.
+ *
+ * Copyright 2012 by Apple Inc.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file. If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * ppdxReadData() - Read encoded data from a ppd_file_t *.
+ * ppdxWriteData() - Writes encoded data to stderr using PPD: messages.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "ppdx.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <zlib.h> /* For compression of the data */
+
+
+/*
+ * Constants...
+ */
+
+#define PPDX_MAX_VALUE (PPD_MAX_LINE - PPD_MAX_NAME - 4)
+ /* Max value length with delimiters + nul */
+#define PPDX_MAX_CHUNK (PPDX_MAX_VALUE * 3 / 4)
+ /* Max length of each chunk when Base64-encoded */
+
+
+/*
+ * 'ppdxReadData()' - Read encoded data from a ppd_file_t *.
+ *
+ * Reads chunked data in the PPD file "ppd" using the prefix "name". Returns
+ * an allocated pointer to the data (which is nul-terminated for convenience)
+ * along with the length of the data in the variable pointed to by "datasize",
+ * which can be NULL to indicate the caller doesn't need the length.
+ *
+ * Returns NULL if no data is present in the PPD with the prefix.
+ */
+
+void * /* O - Data or NULL */
+ppdxReadData(ppd_file_t *ppd, /* I - PPD file */
+ const char *name, /* I - Keyword prefix */
+ size_t *datasize) /* O - Size of data or NULL for don't care */
+{
+ char keyword[PPD_MAX_NAME], /* Keyword name */
+ decoded[PPDX_MAX_CHUNK + 1];
+ /* Decoded string */
+ unsigned chunk = 0; /* Current chunk number */
+ int len; /* Length of current chunk */
+ ppd_attr_t *attr; /* Keyword/value from PPD file */
+ Bytef *data; /* Pointer to data */
+ size_t alloc_size; /* Allocated size of data buffer */
+ z_stream decomp; /* Decompressor stream */
+ int error; /* Error/status from inflate() */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (datasize)
+ *datasize = 0;
+
+ if (!ppd || !name)
+ return (NULL);
+
+ /*
+ * First see if there are any instances of the named keyword in the PPD...
+ */
+
+ snprintf(keyword, sizeof(keyword), "%s%04x", name, chunk);
+ if ((attr = ppdFindAttr(ppd, keyword, NULL)) == NULL)
+ return (NULL);
+
+ /*
+ * Allocate some memory and start decoding...
+ */
+
+ data = malloc(257);
+ alloc_size = 256;
+
+ memset(&decomp, 0, sizeof(decomp));
+ decomp.next_out = data;
+ decomp.avail_out = 256;
+
+ inflateInit(&decomp);
+
+ do
+ {
+ /*
+ * Grab the data from the current attribute and decode it...
+ */
+
+ len = sizeof(decoded);
+ if (!httpDecode64_2(decoded, &len, attr->value) || len == 0)
+ break;
+
+// printf("chunk %04x has length %d\n", chunk, len);
+
+ /*
+ * Decompress this chunk...
+ */
+
+ decomp.next_in = decoded;
+ decomp.avail_in = len;
+
+ do
+ {
+ Bytef *temp; /* Temporary pointer */
+ size_t temp_size; /* Temporary allocation size */
+
+// printf("Before inflate: avail_in=%d, avail_out=%d\n", decomp.avail_in,
+// decomp.avail_out);
+
+ if ((error = inflate(&decomp, Z_NO_FLUSH)) < Z_OK)
+ {
+ fprintf(stderr, "ERROR: inflate returned %d (%s)\n", error, decomp.msg);
+ break;
+ }
+
+// printf("After inflate: avail_in=%d, avail_out=%d, error=%d\n",
+// decomp.avail_in, decomp.avail_out, error);
+
+ if (decomp.avail_out == 0)
+ {
+ if (alloc_size < 2048)
+ temp_size = alloc_size * 2;
+ else if (alloc_size < PPDX_MAX_DATA)
+ temp_size = alloc_size + 2048;
+ else
+ break;
+
+ if ((temp = realloc(data, temp_size + 1)) == NULL)
+ {
+ free(data);
+ return (NULL);
+ }
+
+ decomp.next_out = temp + (decomp.next_out - data);
+ decomp.avail_out = temp_size - alloc_size;
+ data = temp;
+ alloc_size = temp_size;
+ }
+ }
+ while (decomp.avail_in > 0);
+
+ chunk ++;
+ snprintf(keyword, sizeof(keyword), "%s%04x", name, chunk);
+ }
+ while ((attr = ppdFindAttr(ppd, keyword, NULL)) != NULL);
+
+ inflateEnd(&decomp);
+
+ /*
+ * Nul-terminate the data (usually a string)...
+ */
+
+ *(decomp.next_out) = '\0';
+
+ if (datasize)
+ *datasize = decomp.next_out - data;
+
+ return (data);
+}
+
+
+/*
+ * 'ppdxWriteData()' - Writes encoded data to stderr using PPD: messages.
+ *
+ * Writes chunked data to the PPD file using PPD: messages sent to stderr for
+ * cupsd. "name" must be a valid PPD keyword string whose length is less than
+ * 37 characters to allow for chunk numbering. "data" provides a pointer to the
+ * data to be written, and "datasize" provides the length.
+ */
+
+extern void
+ppdxWriteData(const char *name, /* I - Base name of keyword */
+ const void *data, /* I - Data to write */
+ size_t datasize) /* I - Number of bytes in data */
+{
+ char buffer[PPDX_MAX_CHUNK], /* Chunk buffer */
+ encoded[PPDX_MAX_VALUE + 1],
+ /* Encoded data */
+ pair[PPD_MAX_LINE], /* name=value pair */
+ line[PPDX_MAX_STATUS], /* Line buffer */
+ *lineptr, /* Current position in line buffer */
+ *lineend; /* End of line buffer */
+ unsigned chunk = 0; /* Current chunk number */
+ int len; /* Length of current chunk */
+ z_stream comp; /* Compressor stream */
+ int error; /* Error/status from deflate() */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (!name || (!data && datasize > 0) || datasize > PPDX_MAX_DATA)
+ return;
+
+ strlcpy(line, "PPD:", sizeof(line));
+ lineptr = line + 4;
+ lineend = line + sizeof(line) - 2;
+
+ if (datasize > 0)
+ {
+ /*
+ * Compress and encode output...
+ */
+
+ memset(&comp, 0, sizeof(comp));
+ comp.next_in = (Bytef *)data;
+ comp.avail_in = datasize;
+
+ deflateInit(&comp, 9);
+
+ do
+ {
+ /*
+ * Compress a chunk...
+ */
+
+ comp.next_out = buffer;
+ comp.avail_out = sizeof(buffer);
+
+ if ((error = deflate(&comp, Z_FINISH)) < Z_OK)
+ {
+ fprintf(stderr, "ERROR: deflate returned %d (%s)\n", error, comp.msg);
+ break;
+ }
+
+ /*
+ * Write a chunk...
+ */
+
+ len = sizeof(buffer) - comp.avail_out;
+ httpEncode64_2(encoded, sizeof(encoded), buffer, len);
+
+ len = (int)snprintf(pair, sizeof(pair), " %s%04x=%s", name, chunk,
+ encoded);
+#ifdef DEBUG
+ fprintf(stderr, "DEBUG: *%s%04x: \"%s\"\n", name, chunk, encoded);
+#endif /* DEBUG */
+
+ if ((lineptr + len) >= lineend)
+ {
+ *lineptr++ = '\n';
+ *lineptr = '\0';
+
+ fputs(line, stderr);
+ lineptr = line + 4;
+ }
+
+ strlcpy(lineptr, pair, lineend - lineptr);
+ lineptr += len;
+
+ /*
+ * Setup for the next one...
+ */
+
+ chunk ++;
+ }
+ while (comp.avail_out == 0);
+ }
+
+ deflateEnd(&comp);
+
+ /*
+ * Write a trailing empty chunk to signal EOD...
+ */
+
+ len = (int)snprintf(pair, sizeof(pair), " %s%04x=\"\"", name, chunk);
+#ifdef DEBUG
+ fprintf(stderr, "DEBUG: *%s%04x: \"\"\n", name, chunk);
+#endif /* DEBUG */
+
+ if ((lineptr + len) >= lineend)
+ {
+ *lineptr++ = '\n';
+ *lineptr = '\0';
+
+ fputs(line, stderr);
+ lineptr = line + 4;
+ }
+
+ strlcpy(lineptr, pair, lineend - lineptr);
+ lineptr += len;
+
+ *lineptr++ = '\n';
+ *lineptr = '\0';
+
+ fputs(line, stderr);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/examples/ppdx.h b/examples/ppdx.h
new file mode 100644
index 000000000..1be6928da
--- /dev/null
+++ b/examples/ppdx.h
@@ -0,0 +1,82 @@
+/*
+ * "$Id$"
+ *
+ * Header for PPD data encoding example code.
+ *
+ * Copyright 2012 by Apple Inc.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file. If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ */
+
+#ifndef _PPDX_H_
+# define _PPDX_H_
+
+
+/*
+ * Include necessary headers...
+ */
+
+# include <cups/ppd.h>
+
+
+/*
+ * C++ magic...
+ */
+
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+
+
+/*
+ * Maximum amount of data to encode/decode...
+ */
+
+# define PPDX_MAX_STATUS 1024 /* Limit on log messages in 10.6 */
+# define PPDX_MAX_DATA 16777216/* 16MiB */
+
+
+/*
+ * 'ppdxReadData()' - Read encoded data from a ppd_file_t *.
+ *
+ * Reads chunked data in the PPD file "ppd" using the prefix "name". Returns
+ * an allocated pointer to the data (which is nul-terminated for convenience)
+ * along with the length of the data in the variable pointed to by "datasize",
+ * which can be NULL to indicate the caller doesn't need the length.
+ *
+ * Returns NULL if no data is present in the PPD with the prefix.
+ */
+
+extern void *ppdxReadData(ppd_file_t *ppd, const char *name,
+ size_t *datasize);
+
+
+/*
+ * 'ppdxWriteData()' - Writes encoded data to stderr using PPD: messages.
+ *
+ * Writes chunked data to the PPD file using PPD: messages sent to stderr for
+ * cupsd. "name" must be a valid PPD keyword string whose length is less than
+ * 37 characters to allow for chunk numbering. "data" provides a pointer to the
+ * data to be written, and "datasize" provides the length.
+ */
+
+extern void ppdxWriteData(const char *name, const void *data,
+ size_t datasize);
+
+
+# ifdef __cplusplus
+}
+# endif /* __cplusplus */
+
+#endif /* !_PPDX_H */
+
+/*
+ * End of "$Id$".
+ */
diff --git a/examples/testppdx.c b/examples/testppdx.c
new file mode 100644
index 000000000..f1c168688
--- /dev/null
+++ b/examples/testppdx.c
@@ -0,0 +1,117 @@
+/*
+ * "$Id$"
+ *
+ * Test program for PPD data encoding example code.
+ *
+ * Compile with:
+ *
+ * gcc -o testppdx -D_PPD_DEPRECATED="" -g testppdx.c ppdx.c -lcups -lz
+ *
+ * Copyright 2012 by Apple Inc.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file. If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * main() - Read data from a test PPD file and write out new chunks.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "ppdx.h"
+
+
+/*
+ * 'main()' - Read data from a test PPD file and write out new chunks.
+ */
+
+int /* O - Exit status */
+main(void)
+{
+ int status = 0; /* Exit status */
+ FILE *fp; /* File to read */
+ char contents[8193], /* Contents of file */
+ *data; /* Data from PPD */
+ size_t contsize, /* File size */
+ datasize; /* Data size */
+ ppd_file_t *ppd; /* Test PPD */
+
+
+ /*
+ * Open the PPD and get the data from it...
+ */
+
+ ppd = ppdOpenFile("testppdx.ppd");
+ data = ppdxReadData(ppd, "EXData", &datasize);
+
+ /*
+ * Open this source file and read it...
+ */
+
+ fp = fopen("testppdx.c", "r");
+ if (fp)
+ {
+ contsize = fread(contents, 1, sizeof(contents) - 1, fp);
+ fclose(fp);
+ contents[contsize] = '\0';
+ }
+ else
+ {
+ contents[0] = '\0';
+ contsize = 0;
+ }
+
+ /*
+ * Compare data...
+ */
+
+ if (data)
+ {
+ if (contsize != datasize)
+ {
+ fprintf(stderr, "ERROR: PPD has %ld bytes, test file is %ld bytes.\n",
+ (long)datasize, (long)contsize);
+ status = 1;
+ }
+ else if (strcmp(contents, data))
+ {
+ fputs("ERROR: PPD and test file are not the same.\n", stderr);
+ status = 1;
+ }
+
+ if (status)
+ {
+ if ((fp = fopen("testppdx.dat", "wb")) != NULL)
+ {
+ fwrite(data, 1, datasize, fp);
+ fclose(fp);
+ fputs("ERROR: See testppdx.dat for data from PPD.\n", stderr);
+ }
+ else
+ perror("Unable to open 'testppdx.dat'");
+ }
+
+ free(data);
+ }
+
+ printf("Encoding %ld bytes for PPD...\n", (long)contsize);
+
+ ppdxWriteData("EXData", contents, contsize);
+
+ return (1);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/examples/testppdx.ppd b/examples/testppdx.ppd
new file mode 100644
index 000000000..179b1ec6c
--- /dev/null
+++ b/examples/testppdx.ppd
@@ -0,0 +1,121 @@
+*PPD-Adobe: "4.3"
+*%
+*% "$Id$"
+*%
+*% Test PPD file for data encoding example.
+*%
+*% This file cannot be used with any known printers.
+*%
+*% Copyright 2007-2012 by Apple Inc.
+*% Copyright 2002-2006 by Easy Software Products.
+*%
+*% These coded instructions, statements, and computer programs are the
+*% property of Apple Inc. and are protected by Federal copyright
+*% law. Distribution and use rights are outlined in the file "LICENSE.txt"
+*% which should have been included with this file. If this file is
+*% file is missing or damaged, see the license at "http://www.cups.org/".
+*FormatVersion: "4.3"
+*FileVersion: "1.3"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "TESTPPDX.PPD"
+*Manufacturer: "Apple"
+*Product: "(Test PPDX)"
+*cupsVersion: 1.6
+*ModelName: "Test PPDX"
+*ShortNickName: "Test PPDX"
+*NickName: "Test PPDX for CUPS"
+*PSVersion: "(3010.000) 0"
+*LanguageLevel: "3"
+*ColorDevice: True
+*DefaultColorSpace: RGB
+*FileSystem: False
+*Throughput: "1"
+*LandscapeOrientation: Plus90
+*TTRasterizer: Type42
+*cupsFilter: "application/vnd.cups-raster 0 -"
+*RequiresPageRegion All: True
+
+*% For PageSize, we have put all of the translations in-line...
+*OpenUI *PageSize/Page Size: PickOne
+*OrderDependency: 10 AnySetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter/US Letter: "PageSize=Letter"
+*PageSize Letter.Banner/US Letter Banner: "PageSize=Letter.Banner"
+*PageSize Letter.Fullbleed/US Letter Borderless: "PageSize=Letter.Fullbleed"
+*PageSize A4/A4: "PageSize=A4"
+*PageSize Env10/#10 Envelope: "PageSize=Env10"
+*CloseUI: *PageSize
+
+*% For PageRegion, we have separated the translations...
+*OpenUI *PageRegion/Page Region: PickOne
+*OrderDependency: 10 AnySetup *PageRegion
+*DefaultPageRegion: Letter
+*PageRegion Letter/US Letter: "PageRegion=Letter"
+*PageRegion Letter.Banner/US Letter Banner: "PageRegion=Letter.Fullbleed"
+*PageRegion Letter.Fullbleed/US Letter Borderless: "PageRegion=Letter.Fullbleed"
+*PageRegion A4/A4: "PageRegion=A4"
+*PageRegion Env10/#10 Envelope: "PageRegion=Env10"
+*CloseUI: *PageRegion
+
+*DefaultImageableArea: Letter
+*ImageableArea Letter: "18 36 594 756"
+*ImageableArea Letter.Banner: "18 0 594 792"
+*ImageableArea Letter.Fullbleed: "0 0 612 792"
+*ImageableArea A4: "18 36 577 806"
+*ImageableArea Env10: "18 36 279 648"
+
+*DefaultPaperDimension: Letter
+*PaperDimension Letter: "612 792"
+*PaperDimension Letter.Banner: "612 792"
+*PaperDimension Letter.Fullbleed: "612 792"
+*PaperDimension A4: "595 842"
+*PaperDimension Env10: "297 684"
+
+*DefaultFont: Courier
+*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
+*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
+*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
+*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
+*Font Bookman-Light: Standard "(001.004S)" Standard ROM
+*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
+*Font Courier: Standard "(002.004S)" Standard ROM
+*Font Courier-Bold: Standard "(002.004S)" Standard ROM
+*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
+*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
+*Font Helvetica: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
+*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
+*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
+*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
+*Font Symbol: Special "(001.007S)" Special ROM
+*Font Times-Bold: Standard "(001.007S)" Standard ROM
+*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
+*Font Times-Italic: Standard "(001.007S)" Standard ROM
+*Font Times-Roman: Standard "(001.007S)" Standard ROM
+*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
+*Font ZapfDingbats: Special "(001.004S)" Standard ROM
+*%
+*% End of "$Id$".
+*%
+*EXData0000: "eNqlVm1v2zYQ/hz/ipvWznLgl6T7siXrgCJ2AANBEyQpNmAtAlqiLG4SKZBU7LTIf9/dUW9Og32ZAFsieffcc88dKS2OR3AM0Zt1+ibCJxoA3EvnobJma0UJmbFwc7OEVHgBUicmVXoLci/KqpCAQznvHC9MWSmc3Smfn3WzdG2TBGYGPCJXVbqH2fIBQR+Wq5vb1cWH+9XyfRTBbNs"
+*EXData0001: "GcwTaG6zIqkrh7evgzDVk1Xb3MO7k9N3sHmCDxWRWeuk53KfSxf4paC087ZOvDLaTcF54WUptcdnoVO0KavaS9um7EBYCT6XAQhnK2n9E5hsEIc9yQ6XvUw8RkEelzKVVhQI2TAMEIXYzQGWClmoTU002L1GgmwVIpraF0ozXYoOGUkZXa0vVh/vVnO/91FA2+UqycHlpi5SyMWjhI0"
+*EXData0002: "lBq9kqKmbEl9BFCOETDwOuuHoFxAaQZQKueooljmVJRiK1NUSHL+UKhEaiQpPES599XZYrHb7eZUkLmx20U0lLsPAK7e/I2agDcME1S7vpst5aMsUM0U7kzmd5S03CeyIkVaqAujPdWm759SKB1PYAa3UqShDzNrShDcLdycHJgk3VnlWUnQcgdJXut/HCEvRqMFw62DSricSOeEfYI"
+*EXData0003: "HFGldfN5Y/djIyT85nyqzDz//WDKolgHcxE3ah6N2hDjQHj8vxkr7Y/oWhzDNYKt9spz89aOljnKo1HpZPRtBMDGzep7ODlntxcuAJfrq9XR0XFWnQfcS6KBZbJElC2SXNijo6Spwl+/nP7685cp27aVoY3A9NEesSi9Bm3ZZUopMpxTX+WDZzx6nPZRaRggCIFG5z1Iuwh0DDxQNAQ"
+*EXData0004: "OcbnJtJ9qyPpNAISHpW/rmTYOrRC4m6l53FfAuW50OzH4IBq4Y1ciVYcdUcQ/kWTc7Rib7baU0GJYIyDKUSrP2kQTeGnNgd0eEmHNoSpbSL7orPch1SyCkNkuDn0gEKC0JENLFQGcVZN8InKjYVqJCU3wovbmk3hdMoCmqybo+2Ds+h/zs5ZUhgn427c1btF/YKw488nY1p+xp8snDw"
+*EXData0005: "CM3WJ0OzASUA7kH27eSgtwNteZJqmDklRnN9ajTTYf3wHjpxeTXYkGK4F30W4zaV1lI1bm+vb8+4+Llw8LagMxm1nIZt155O3fz8s46mDVh7xYXR20kbcNqMWzKNWgDdRjsNM8/8TyIxeTwmkrIaVITze0m/9i4ekqbO6JmSVNqE/nWilMwWQrL/waMTMCwdxqT5+NVOQ4LUa7tNNJk"
+*EXData0006: "kOQfP11dTRqvb51GGZ9WXC3usl6nrpNe667v072jN8wgNn9mpMPj49V0n5t7043hwrezNTaOPmmxCacZ5QbjIf44mhwIhDsmpDFpmxSabopW7TdO1yftNxA2LZP6rifCSbL/g8Th06E/GPoWOLS30tdWQ3yKw+fu1bHCDsDTNXyPhbfAvwxF0gE="
+*EXData0007: ""