Example #1
0
 public Command Receive(ref System.IO.MemoryStream stream, ref IPEndPoint ipendpoint)
 {
     var receiveBytes = UDP.Receive(ref ipendpoint);
     stream.SetLength(0); // Очистка потока
     stream.Write(receiveBytes, 0, receiveBytes.Length);
     stream.Seek(0, System.IO.SeekOrigin.Begin);
     return (m_biFormatter.Deserialize(stream) as Command);
 }
Example #2
0
        internal void Write(System.IO.Stream outstream)
        {
            if (_Source == EntrySource.Zipfile)
            {
                CopyThroughOneEntry(outstream);
                return;
            }

            // Ok, the source for this entry is not a previously created zip file.  Therefore we
            // will need to process the bytestream (compute crc, maybe compress, maybe encrypt)
            // in order to create the zip.
            //
            // We do this in potentially 2 passes: The first time we do it as requested, maybe
            // with compression and maybe encryption.  If that causes the bytestream to inflate
            // in size, and if compression was on, then we turn off compression and do it again.

            bool readAgain = true;
            int nCycles = 0;
            do
            {
                nCycles++;

                // write the header:
                WriteHeader(outstream, nCycles);

                if (IsDirectory) return;  // nothing more to do!

                ZipCrypto cipher = null;

                // now, write the actual file data. (incl the encrypted header)
                _EmitOne(outstream, out cipher);

                // The file data has now been written to the stream, and
                // the file pointer is positioned directly after file data.

                if (nCycles > 1) readAgain = false;
                else if (!outstream.CanSeek) readAgain = false;
                else if (cipher != null && CompressedSize - 12 <= UncompressedSize) readAgain = false;
                else readAgain = WantReadAgain();

                if (readAgain)
                {
                    // seek back!
                    // seek in the raw output stream, to the beginning of the file data for this entry
                    outstream.Seek(_RelativeOffsetOfHeader, System.IO.SeekOrigin.Begin);

                    // if the last entry expands, we read again; but here, we must truncate the stream
                    // to prevent garbage data after the end-of-central-directory.
                    outstream.SetLength(outstream.Position);

                    // adjust the count on the CountingStream as necessary
                    var s1 = outstream as CountingStream;
                    if (s1 != null) s1.Adjust(_TotalEntrySize);
                }
            }
            while (readAgain);
        }
		/// <summary>
		/// Renders a document as enhanced metafile. The metafile is rendered into a stream. You can create a metafile object afterwards from that stream.
		/// </summary>
		/// <param name="renderingProc">Procedure for rendering the document.
		/// The argument is a graphics context, which is set to GraphicsUnits equal to Points.
		/// The drawing must be inside of the boundaries of docSize.X and docSize.Y.
		/// </param>
		/// <param name="stream">Destination stream. The metafile is rendered into this stream. The stream has to be writeable and seekable. At return, the position of the stream is set to 0, thus the stream is ready to be used to create a metafile object from it.</param>
		/// <param name="docSize">Size of the document in points (1/72 inch)</param>
		/// <param name="sourceDpiResolution">The resolution in dpi of the source. This parameter is used only if creating the reference graphics context from the current printer fails. In this case, a context from a bitmap with the provided resolution is created.</param>
		/// <param name="outputScalingFactor">Output scaling factor. If less than 1, the image will appear smaller than originally, if greater than 1, the image will appear larger than originally.</param>
		/// <param name="pixelFormat">Optional: Only used if the graphics context can not be created from a printer document. Pixel format of the bitmap that is used in this case to construct the graphics context.</param>
		/// <returns>The rendered enhanced metafile (vector format).</returns>
		/// <remarks>
		/// <para>
		/// I found no other way to realize different dpi resolutions, independently of screen or printer device contexts, as to patch the resulting metafile stream with
		/// informations about an 'artifical' device, which has exactly the resolution that is neccessary. By careful choice of the size of this artifical device one can
		/// avoid rounding errors concerning resolution and size.
		/// It happens that some programs (for instance MS Word 2010 when saving as PDF document) mess up the size of the metafile graphics, if the graphics was created with a PageUnit
		/// (of the graphics context) other than PIXELS.
		/// Thus I now always use PIXEL as PageUnit and scale the graphics context accordingly.
		/// </para>
		/// <para>
		/// Another problem, which is actually without solution, is that e.g. MS Office will not show polylines with more than 8125 points. These polylines are included in the metafile,
		/// but MS Office seems to ignore them. On the other hand, CorelDraw X5 can show these polylines correctly.
		/// This problem might be related to the EmfPlus format, because MS Office will show these polylines if the EmfOnly format is used. But EmfOnly can not handle transparencies, thus
		/// it is not really a choice.
		/// </para>
		/// </remarks>
		public static void RenderAsEnhancedMetafileToStream(Action<Graphics> renderingProc, System.IO.Stream stream, PointD2D docSize, double sourceDpiResolution, double outputScalingFactor, PixelFormat pixelFormat = PixelFormat.Format32bppArgb)
		{
			if (stream == null)
				throw new ArgumentNullException("stream");
			if (!stream.CanWrite)
				throw new ArgumentException("stream is not writeable");
			if (!stream.CanSeek)
				throw new ArgumentException("stream is not seekable");
			stream.SetLength(0);

			var scaledDocSize = docSize * outputScalingFactor;

			// our artifical device has a square size, and the size is an integer multiple of 5 inch (5 inch because this is the smallest size which converts to an integer number of millimeters: 127 mm)
			int deviceSizeInch = (int)(5 * Math.Ceiling(Math.Max(scaledDocSize.X, scaledDocSize.Y) / (72 * 5)));

			// we have to design our artifical device so that it has a resolution of sourceDpiResolution/outputScalingFactor
			// this accounts for the fact, that if
			double deviceResolution = sourceDpiResolution / outputScalingFactor;

			// then the number of pixels of the device is simple the device size in inch times the device resolution
			int devicePixelsX = (int)Math.Round(deviceSizeInch * deviceResolution);
			int devicePixelsY = (int)Math.Round(deviceSizeInch * deviceResolution);

			// device size in millimeter. Because of the choice of the device size (see above) there should be no rounding errors here
			int deviceSizeXMillimeter = (deviceSizeInch * 254) / 10;
			int deviceSizeYMillimeter = (deviceSizeInch * 254) / 10;

			// device size in micrometer
			int deviceSizeXMicrometer = deviceSizeInch * 25400;
			int deviceSizeYMicrometer = deviceSizeInch * 25400;

			// bounds of the graphic in pixels. Because it is in pixels, it is calculated with the unscaled size of the document and the sourceDpiResolution
			int graphicBoundsLeft_Pixels = 0;
			int graphicBoundsTop_Pixels = 0;
			int graphicBoundsWidth_Pixels = (int)Math.Ceiling(sourceDpiResolution * docSize.X / 72);
			int graphicBoundsHeight_Pixels = (int)Math.Ceiling(sourceDpiResolution * docSize.Y / 72);

			// position and size of the bounding box. Please not that the bounds are scaled with the outputScalingFactor
			int boundingBoxLeft_HIMETRIC = 0;
			int boundingBoxTop_HIMETRIC = 0;
			int boundingBoxWidth_HIMETRIC = (int)Math.Ceiling(scaledDocSize.X * 2540.0 / 72);
			int boundingBoxHeight_HIMETRIC = (int)Math.Ceiling(scaledDocSize.Y * 2540.0 / 72);

			Metafile metafile;
			using (var helperbitmap = new System.Drawing.Bitmap(4, 4, PixelFormat.Format32bppArgb))
			{
				using (Graphics grfxReference = Graphics.FromImage(helperbitmap))
				{
					IntPtr deviceContextHandle = grfxReference.GetHdc();

					metafile = new Metafile(
					stream,
					deviceContextHandle,
					new RectangleF(boundingBoxLeft_HIMETRIC, boundingBoxTop_HIMETRIC, boundingBoxWidth_HIMETRIC, boundingBoxHeight_HIMETRIC),
					MetafileFrameUnit.GdiCompatible,
					EmfType.EmfPlusDual); // EmfOnly is working with PolyLines with more than 8125 Points, but can not handle transparencies  // EmfPlusDual and EmfPlusOnly: there is no display of polylines with more than 8125 points, although the polyline seems embedded in the EMF. // EmfPlusOnly can not be converted to WMF

					grfxReference.ReleaseHdc();
				}
			}

			using (Graphics grfxMetafile = Graphics.FromImage(metafile))
			{
				// Set everything to high quality
				grfxMetafile.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
				grfxMetafile.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;

				// 2014-10-10 Setting InterpolationMode to HighQualityBicubic and PixelOffsetMode to HighQuality
				// causes problems when rendering small bitmaps (at a large magnification, for instance the density image legend):
				// the resulting image seems a litte soft, the colors somehow distorted, so I decided not to use them here any more

				//grfxMetafile.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
				//grfxMetafile.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;

				grfxMetafile.PageUnit = GraphicsUnit.Pixel; // Attention: always use pixels here. Any other choice will cause problems in some programs (see remarks above).
				grfxMetafile.PageScale = (float)(sourceDpiResolution / 72.0); // because our choice of GraphicsUnit is pixels, at the resolution of 72 dpi one point is one pixel. At a higher resolution, one point is more than one pixel.

				grfxMetafile.SetClip(new RectangleF(0, 0, (float)docSize.X, (float)docSize.Y));
				renderingProc(grfxMetafile);
			}
			stream.Flush();

			// we have to patch the resulting metafile stream with the parameters of the graphics and the device

			stream.Position = 0x04;
			var buf4 = new byte[4];
			stream.Read(buf4, 0, 4);
			int headerSize = BitConverter.ToInt32(buf4, 0); // Read the header size to make sure that Metafile header extension 2 is present

			// At position 0x08 there are the bounds of the graphic (not the bounding box, but the box for all the graphical elements)
			stream.Position = 0x08;
			stream.Write(BitConverter.GetBytes(graphicBoundsLeft_Pixels), 0, 4);
			stream.Write(BitConverter.GetBytes(graphicBoundsTop_Pixels), 0, 4);
			stream.Write(BitConverter.GetBytes(graphicBoundsWidth_Pixels), 0, 4);
			stream.Write(BitConverter.GetBytes(graphicBoundsHeight_Pixels), 0, 4);

			// At position 0x48 the device parameters are located: here the number of pixels of the device
			stream.Position = 0x48;
			stream.Write(BitConverter.GetBytes(devicePixelsX), 0, 4); //  the number of pixels of the device X
			stream.Write(BitConverter.GetBytes(devicePixelsY), 0, 4);  // the number of pixels of the device Y
			stream.Write(BitConverter.GetBytes(deviceSizeXMillimeter), 0, 4); // size X of the device in millimeter
			stream.Write(BitConverter.GetBytes(deviceSizeYMillimeter), 0, 4); // size Y of the device in millimeter

			if (headerSize >= (0x64 + 0x08))
			{
				stream.Position = 0x64;
				stream.Write(BitConverter.GetBytes(deviceSizeXMicrometer), 0, 4); // size X of the device in micrometer
				stream.Write(BitConverter.GetBytes(deviceSizeYMicrometer), 0, 4); // size Y of the device in micrometer
			}

			stream.Flush();

			stream.Position = 0;

			metafile.Dispose(); // we can safely dispose this metafile, because stream and metafile are independent of each other, and only the stream is patched
		}
Example #4
0
        /// <summary>
        /// Retrieves the identified data from the server.
        /// </summary>
        /// <returns>
        /// Returns the content's MIME and the decompressed data as a stream (optionally that
        /// supplied as <c>output_file</c>), along with the length of the content in bytes.
        /// </returns>
        /// <param name='uid'>
        /// The UID of the record to be retrieved.
        /// </param>
        /// <param name='read_key'>
        /// A token that grants permission to read the record.
        /// </param>
        /// <param name='output_file'>
        /// An optional stream into which retrieved content may be written; if <c>null</c>, the
        /// default, an on-disk, self-cleaning tempfile, is used instead.
        /// </param>
        /// <param name='decompress_on_server'>
        /// Favours decompression of content on the server; defaults to <c>false</c>.
        /// </param>
        /// <param name='timeout'>
        /// The number of seconds to wait for a response; defaults to 5.
        /// </param>
        /// <exception cref="System.Exception">
        /// Some unknown problem occurred.
        /// </exception>
        /// <exception cref="Exceptions.ProtocolError">
        /// A problem occurred related to the transport protocol.
        /// </exception>
        /// <exception cref="Exceptions.UrlError">
        /// A problem occurred related to the network environment.
        /// </exception>
        /// <exception cref="Exceptions.NotFoundError">
        /// The requested record was not found.
        /// </exception>
        /// <exception cref="Exceptions.NotAuthorisedError">
        /// The requested record was not accessible with the given credentials.
        /// </exception>
        public Structures.Internal.Content Get(string uid, string read_key, System.IO.Stream output_file=null, bool decompress_on_server=false, float timeout=5.0f)
        {
            Jayrock.Json.JsonObject get_json = new Jayrock.Json.JsonObject();
            get_json.Add("uid", uid);

            Jayrock.Json.JsonObject keys = new Jayrock.Json.JsonObject();
            keys.Add("read", read_key);
            get_json.Add("keys", keys);

            System.Collections.Generic.Dictionary<string, string> headers = new System.Collections.Generic.Dictionary<string, string>();
            if(!decompress_on_server){
                headers.Add(Libraries.Communication.HEADER_SUPPORTED_COMPRESSION, string.Join(Libraries.Communication.HEADER_SUPPORTED_COMPRESSION_DELIMITER.ToString(), Libraries.Compression.SupportedFormats));
            }

            System.Net.HttpWebRequest request = Libraries.Communication.AssembleRequest(this.server.GetHost() + Libraries.Communication.SERVER_GET, get_json, headers:headers);

            System.IO.Stream output;
            if(output_file != null){
                output = output_file;
            }else{
                output = new Libraries.TempFileStream();
            }

            Libraries.Communication.Response response = Libraries.Communication.SendRequest(request, output:output, timeout:timeout);

            Structures.Internal.Content content = new Structures.Internal.Content();
            content.Data = response.Data;
            content.Mime = (string)response.Properties[Libraries.Communication.PROPERTY_CONTENT_TYPE];
            content.Length = (long)response.Properties[Libraries.Communication.PROPERTY_CONTENT_LENGTH];

            //Evaluate decompression requirements
            object applied_compression = response.Properties[Libraries.Communication.PROPERTY_APPLIED_COMPRESSION];
            if(applied_compression != null){
                System.IO.Stream decompressed_data = Libraries.Compression.GetDecompressor((COMPRESSION)applied_compression).Invoke(content.Data);
                if(output_file != null){ //Write to the given stream, since the caller might expect to use that
                    output_file.Seek(0, System.IO.SeekOrigin.Begin);
                    output_file.SetLength(0); //Truncate the file
                    decompressed_data.CopyTo(output_file);
                    output_file.Seek(0, System.IO.SeekOrigin.Begin);
                    content.Data = output_file;
                    content.Length = output_file.Length;
                }
            }

            return content;
        }