private void WriteHeader(string path, long contentSize, DateTime? lastModified = null, DateTime? created = null, int mode = 511, EntryType entryType = EntryType.File, int userId = 61, int groupId = 61) { OAFFileHeader header = new OAFFileHeader(); header.path = path.Replace(Path.DirectorySeparatorChar, '/'); header.contentSize = contentSize; header.contentFullSize = contentSize; header.lastModified = lastModified; header.created = created; header.mode = mode; header.userId = userId; header.groupId = groupId; header.entryType = entryType; // Just put content in next available space header.contentRelativePos = 0; // Header Compression not implemented header.hCompression = CompressionType.None; // Content Compression not implemented header.cCompression = CompressionType.None; // Hashing not implemented header.contentHashType = HashType.None; header.contentHash = 0; header.headerHashType = HashType.None; header.headerHash = 0; WriteHeader(header); }
private OAFFileHeader ImpossibleHeader() { OAFFileHeader header = new OAFFileHeader(); // set some impossible values header.headerPosition = -1; header.headerSize = -1; header.contentSize = -1; return header; }
private void WriteHeader(OAFFileHeader header) { MemoryStream hStream = new MemoryStream(); int headerSize = 0; long timeModified; if (header.lastModified == null) timeModified = DateTime.Now.ToFileTimeUtc() - 116444736000000000; else timeModified = header.lastModified.Value.ToFileTimeUtc() - 116444736000000000; long timeCreated; if (header.created == null) timeCreated = timeModified; else timeCreated = header.created.Value.ToFileTimeUtc() - 116444736000000000; byte[] path = ToBytes(header.path); SimpleWrite(hStream, Marker.Open , ref headerSize); // "<ITEM>" SimpleWrite(hStream, ToBytes( (int)-1), ref headerSize); // placeholder for header length SimpleWrite(hStream, ToBytes( (byte)header.hCompression), ref headerSize); SimpleWrite(hStream, ToBytes( (byte)header.headerHashType), ref headerSize); SimpleWrite(hStream, ToBytes( header.headerHash), ref headerSize); SimpleWrite(hStream, ToBytes( path.Length), ref headerSize); SimpleWrite(hStream, path , ref headerSize); SimpleWrite(hStream, ToBytes( header.contentRelativePos), ref headerSize); SimpleWrite(hStream, ToBytes( header.contentSize), ref headerSize); SimpleWrite(hStream, ToBytes( header.contentFullSize), ref headerSize); SimpleWrite(hStream, ToBytes( (byte)header.cCompression), ref headerSize); SimpleWrite(hStream, ToBytes( timeModified), ref headerSize); SimpleWrite(hStream, ToBytes( timeCreated), ref headerSize); SimpleWrite(hStream, ToBytes( header.mode), ref headerSize); SimpleWrite(hStream, ToBytes( header.userId), ref headerSize); SimpleWrite(hStream, ToBytes( header.groupId), ref headerSize); SimpleWrite(hStream, ToBytes( (byte)header.entryType), ref headerSize); SimpleWrite(hStream, ToBytes((byte)header.contentHashType), ref headerSize); SimpleWrite(hStream, ToBytes( header.contentHash), ref headerSize); SimpleWrite(hStream, Marker.Close , ref headerSize); // "</ITEM>" hStream.Position = Marker.Open.Length; SimpleWrite(hStream, ToBytes(headerSize), ref headerSize); // write to Archive hStream.Position = 0; hStream.CopyTo(ArchiveStream); ArchiveStream.Flush(); }
private OAFFileHeader FindNextHeader(long lookFrom = -1, int max_buffer = 4096) { OAFFileHeader header = new OAFFileHeader(); long position = ArchiveStream.Position; while (lookFrom < ArchiveStream.Length) { if (lookFrom > position) { ArchiveStream.Position = lookFrom; } else { lookFrom = position; } int sizeRead = 0; int lastRead; byte[] buffer = new byte[max_buffer]; while (0 < (lastRead = ArchiveStream.Read(buffer, sizeRead, max_buffer - sizeRead))) { sizeRead += lastRead; if ((max_buffer - sizeRead) <= 0) break; } ArchiveStream.Position = position; buffer = Slice(buffer, 0, sizeRead); int offset = 0; while (offset < (sizeRead - Marker.Open.Length + Marker.Close.Length)) { int index = IndexOf(buffer, Marker.Open, offset); if (index < 0 || sizeRead < (index + Marker.Open.Length + 4) ) { // no more chance of finding a header in this buffer :( break; } header.headerSize = ToInt(Slice(buffer, index + Marker.Open.Length, index + Marker.Open.Length + 4)); if (sizeRead < (index + header.headerSize)) { if (ArchiveStream.Length < (lookFrom + index + header.headerSize)) return ImpossibleHeader(); return FindNextHeader(lookFrom + index, header.headerSize); } if (-1 == IndexOf(Slice(buffer, index + header.headerSize - Marker.Close.Length, index + header.headerSize), Marker.Close)) { // not a header :( try again offset += index + 1; continue; } // great, we're pretty sure it's a header! header.headerPosition = position + index; buffer = Slice(buffer, index, index + header.headerSize); // build the struct int detailOffset = Marker.Open.Length + 4; header.hCompression = (CompressionType)ToByte(GetNextDetail(buffer, 1, ref detailOffset)); // if compressed then decompress buffer.. // .. now get other details int pathLength = ToInt(GetNextDetail(buffer, 4, ref detailOffset)); header.path = ToString(GetNextDetail(buffer, pathLength, ref detailOffset)); header.contentRelativePos = ToLong(GetNextDetail(buffer, 8, ref detailOffset)); header.contentSize = ToLong(GetNextDetail(buffer, 8, ref detailOffset)); header.contentFullSize = ToLong(GetNextDetail(buffer, 8, ref detailOffset)); header.cCompression = (CompressionType)ToByte(GetNextDetail(buffer, 1, ref detailOffset)); long time = ToLong(GetNextDetail(buffer, 8, ref detailOffset)); header.lastModified = DateTime.FromFileTimeUtc(time + 116444736000000000); time = ToLong(GetNextDetail(buffer, 8, ref detailOffset)); header.created = DateTime.FromFileTimeUtc(time + 116444736000000000); header.mode = ToInt(GetNextDetail(buffer, 4, ref detailOffset)); header.userId = ToInt(GetNextDetail(buffer, 4, ref detailOffset)); header.groupId = ToInt(GetNextDetail(buffer, 4, ref detailOffset)); byte entryType = ToByte(GetNextDetail(buffer, 1, ref detailOffset)); header.entryType = (EntryType)entryType; byte contentHashType = ToByte(GetNextDetail(buffer, 1, ref detailOffset)); header.contentHashType = (HashType)contentHashType; header.contentHash = ToLong(GetNextDetail(buffer, 8, ref detailOffset)); byte headerHashType = ToByte(GetNextDetail(buffer, 1, ref detailOffset)); header.headerHashType = (HashType)headerHashType; header.headerHash = ToLong(GetNextDetail(buffer, 8, ref detailOffset)); return header; } if (ArchiveStream.Length <= (lookFrom + sizeRead - (Marker.Open.Length - 1) + 4 + Marker.Close.Length)) { // EOF break; } lookFrom += sizeRead - (Marker.Open.Length - 1) - 4; } return ImpossibleHeader(); }