private static void WriteTiltZipHeader(Stream s, TiltZipHeader header) { unsafe { // This doesn't work because we need a byte[] to pass to Stream // byte* bufp = stackalloc byte[sizeof(TiltZipHeader)]; // This doesn't work because the type is also byte*, not byte[] // unsafe struct Foo { fixed byte buf[N]; } Debug.Assert( HEADER_SIZE == Marshal.SizeOf(header), "Reference types detected in TiltZipHeader"); byte[] buf = new byte[HEADER_SIZE]; fixed(byte *bufp = buf) { IntPtr bufip = (IntPtr)bufp; // Copy from undefined CLR layout to explicitly-defined layout Marshal.StructureToPtr(header, bufip, false); s.Write(buf, 0, buf.Length); // Need this if there are reference types, but in that case // there are other complications (like demarshaling) // Marshal.DestroyStructure(bufip, typeof(TiltZipHeader)); } } }
public AtomicWriter(string path) { m_destination = path; m_temporaryPath = path + "_part"; Destroy(m_temporaryPath); bool useZip; switch (DevOptions.I.PreferredTiltFormat) { case TiltFormat.Directory: useZip = false; break; case TiltFormat.Inherit: useZip = !Directory.Exists(path); break; default: case TiltFormat.Zip: useZip = true; break; } if (useZip) { Directory.CreateDirectory(Path.GetDirectoryName(m_temporaryPath)); FileStream tmpfs = new FileStream(m_temporaryPath, FileMode.Create, FileAccess.Write); var header = new TiltZipHeader { sentinel = TILT_SENTINEL, headerSize = HEADER_SIZE, headerVersion = HEADER_VERSION, }; WriteTiltZipHeader(tmpfs, header); m_zipstream = new ZipLibrary.ZipOutputStream(tmpfs); #if USE_DOTNETZIP // Ionic.Zip documentation says that using compression level None produces // zip files that cannot be opened with the default OSX zip reader. // But compression _method_ none seems fine? m_zipstream.CompressionMethod = ZipLibrary.CompressionMethod.None; m_zipstream.EnableZip64 = ZipLibrary.Zip64Option.Never; #else m_zipstream.SetLevel(0); // no compression // Since we don't have size info up front, it conservatively assumes 64-bit. // We turn it off to maximize compatibility with wider ecosystem (eg, osx unzip). m_zipstream.UseZip64 = ZipLibrary.UseZip64.Off; #endif } else { Directory.CreateDirectory(m_temporaryPath); } }