1d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Protocol Buffers - Google's data interchange format 2d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Copyright 2008 Google Inc. All rights reserved. 3d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// http://code.google.com/p/protobuf/ 4d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// 5d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Redistribution and use in source and binary forms, with or without 6d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// modification, are permitted provided that the following conditions are 7d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// met: 8d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// 9d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// * Redistributions of source code must retain the above copyright 10d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// notice, this list of conditions and the following disclaimer. 11d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// * Redistributions in binary form must reproduce the above 12d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// copyright notice, this list of conditions and the following disclaimer 13d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// in the documentation and/or other materials provided with the 14d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// distribution. 15d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// * Neither the name of Google Inc. nor the names of its 16d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// contributors may be used to endorse or promote products derived from 17d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// this software without specific prior written permission. 18d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// 19d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 31d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Author: ambrose@google.com (Ambrose Feinstein), 32d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// kenton@google.com (Kenton Varda) 33d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// 34d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Based on http://www.pkware.com/documents/casestudies/APPNOTE.TXT 35d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 36d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <google/protobuf/compiler/zip_writer.h> 37d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <google/protobuf/io/coded_stream.h> 38d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 39d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillenamespace google { 40d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillenamespace protobuf { 41d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillenamespace compiler { 42d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 43d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillestatic const uint32 kCRC32Table[256] = { 44d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 45d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 46d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 47d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 48d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 49d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 50d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 51d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 52d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 53d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 54d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 55d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 56d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 57d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 58d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 59d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 60d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 61d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 62d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 63d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 64d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 65d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 66d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 67d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 68d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 69d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 70d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 71d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 72d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 73d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 74d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 75d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 76d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 77d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 78d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 79d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 80d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 81d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 82d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 83d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 84d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 85d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 86d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d 87d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}; 88d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 89d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillestatic uint32 ComputeCRC32(const string &buf) { 90d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville uint32 x = ~0U; 91d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for (int i = 0; i < buf.size(); ++i) { 92d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville unsigned char c = buf[i]; 93d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville x = kCRC32Table[(x ^ c) & 0xff] ^ (x >> 8); 94d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 95d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return ~x; 96d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 97d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 98d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillestatic void WriteShort(io::CodedOutputStream *out, uint16 val) { 99d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville uint8 p[2]; 100d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville p[0] = static_cast<uint8>(val); 101d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville p[1] = static_cast<uint8>(val >> 8); 102d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville out->WriteRaw(p, 2); 103d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 104d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 105d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleZipWriter::ZipWriter(io::ZeroCopyOutputStream* raw_output) 106d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville : raw_output_(raw_output) {} 107d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleZipWriter::~ZipWriter() {} 108d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 109d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillebool ZipWriter::Write(const string& filename, const string& contents) { 110d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville FileInfo info; 111d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 112d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville info.name = filename; 113d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville uint16 filename_size = filename.size(); 114d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville info.offset = raw_output_->ByteCount(); 115d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville info.size = contents.size(); 116d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville info.crc32 = ComputeCRC32(contents); 117d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 118d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville files_.push_back(info); 119d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 120d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // write file header 121d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville io::CodedOutputStream output(raw_output_); 122d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville output.WriteLittleEndian32(0x04034b50); // magic 123d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, 10); // version needed to extract 124d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, 0); // flags 125d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, 0); // compression method: stored 126d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, 0); // last modified time 127d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, 0); // last modified date 128d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville output.WriteLittleEndian32(info.crc32); // crc-32 129d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville output.WriteLittleEndian32(info.size); // compressed size 130d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville output.WriteLittleEndian32(info.size); // uncompressed size 131d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, filename_size); // file name length 132d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, 0); // extra field length 133d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville output.WriteString(filename); // file name 134d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville output.WriteString(contents); // file data 135d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 136d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return !output.HadError(); 137d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 138d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 139d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillebool ZipWriter::WriteDirectory() { 140d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville uint16 num_entries = files_.size(); 141d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville uint32 dir_ofs = raw_output_->ByteCount(); 142d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 143d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // write central directory 144d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville io::CodedOutputStream output(raw_output_); 145d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for (int i = 0; i < num_entries; ++i) { 146d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const string &filename = files_[i].name; 147d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville uint16 filename_size = filename.size(); 148d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville uint32 crc32 = files_[i].crc32; 149d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville uint32 size = files_[i].size; 150d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville uint32 offset = files_[i].offset; 151d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 152d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville output.WriteLittleEndian32(0x02014b50); // magic 153d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, 10); // version made by 154d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, 10); // version needed to extract 155d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, 0); // flags 156d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, 0); // compression method: stored 157d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, 0); // last modified time 158d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, 0); // last modified date 159d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville output.WriteLittleEndian32(crc32); // crc-32 160d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville output.WriteLittleEndian32(size); // compressed size 161d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville output.WriteLittleEndian32(size); // uncompressed size 162d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, filename_size); // file name length 163d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, 0); // extra field length 164d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, 0); // file comment length 165d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, 0); // starting disk number 166d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, 0); // internal file attributes 167d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville output.WriteLittleEndian32(0); // external file attributes 168d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville output.WriteLittleEndian32(offset); // local header offset 169d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville output.WriteString(filename); // file name 170d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 171d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville uint32 dir_len = output.ByteCount(); 172d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 173d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // write end of central directory marker 174d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville output.WriteLittleEndian32(0x06054b50); // magic 175d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, 0); // disk number 176d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, 0); // disk with start of central directory 177d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, num_entries); // central directory entries (this disk) 178d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, num_entries); // central directory entries (total) 179d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville output.WriteLittleEndian32(dir_len); // central directory byte size 180d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville output.WriteLittleEndian32(dir_ofs); // central directory offset 181d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WriteShort(&output, 0); // comment length 182d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 183d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return output.HadError(); 184d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 185d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 186d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} // namespace google 187d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} // namespace protobuf 188d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} // namespace compiler 189