Loading...
/* * Copyright (c) 2022 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ // mach_o_writer #include "ArchiveWriter.h" // stl #include <string_view> // Darwin #include <ar.h> #include <mach-o/ranlib.h> #include <mach/mach.h> #include <mach/vm_map.h> namespace mach_o { size_t ArchiveWriter::size(std::span<const Member> members, bool extendedFormatNames) { size_t size = archive_magic.size(); for ( const Member& m : members ) { size += Entry::entrySize(extendedFormatNames, m.name, m.contents.size()); } return size; } Error ArchiveWriter::make(std::span<uint8_t> buffer, std::span<const Member> members, bool extendedFormatNames) { if ( buffer.size() < archive_magic.size() ) { return Error("buffer to small"); } std::span<uint8_t> remainingSpace = buffer; memcpy(remainingSpace.data(), archive_magic.data(), archive_magic.size()); remainingSpace = remainingSpace.subspan(archive_magic.size()); for ( const Member& m : members ) { size_t writtenBytes = Entry::write(remainingSpace, extendedFormatNames, m.name, m.mtime, m.contents); if ( writtenBytes > remainingSpace.size() ) { assert(false && "invalid buffer size"); return Error("buffer to small"); } remainingSpace = remainingSpace.subspan(writtenBytes); } assert(remainingSpace.empty()); if ( isArchive(buffer).has_value() ) return Error::none(); return Error("error writing archive"); } } // namespace mach_o |