#ifndef __DYLD_CLOSURE_BUFFER_H__
#define __DYLD_CLOSURE_BUFFER_H__
#include "Logging.h"
#include "LaunchCache.h"
#include "PathOverrides.h"
namespace dyld3 {
class VIS_HIDDEN TypedContentBuffer
{
public:
TypedContentBuffer(size_t elementsCount, size_t elementsTotalSize);
void addItem(uint32_t k, const void* content, size_t len);
void doneBuilding();
vm_address_t vmBuffer() const;
uint32_t vmBufferSize() const;
TypedContentBuffer(const void* buff, size_t buffSize);
unsigned count(uint32_t) const;
void forEach(uint32_t, void (^callback)(const void* content, size_t length)) const;
void free();
private:
struct Element
{
uint32_t kind;
uint32_t contentLength;
uint8_t content[];
const Element* next() const;
};
size_t _size;
Element* _buffer;
Element* _currentEnd;
bool _readOnly;
};
class VIS_HIDDEN ClosureBuffer : public TypedContentBuffer
{
public:
struct CacheIdent
{
uint8_t cacheUUID[16];
uint64_t cacheAddress;
uint64_t cacheMappedSize;
};
ClosureBuffer(const CacheIdent&, const char* path, const launch_cache::ImageGroupList& groups, const PathOverrides& envVars);
ClosureBuffer(const char* errorMessage);
ClosureBuffer(const launch_cache::BinaryImageGroupData* imageGroupResult);
ClosureBuffer(const launch_cache::BinaryClosureData* closureResult);
bool isError() const;
const char* errorMessage() const;
const launch_cache::BinaryClosureData* closure() const;
const launch_cache::BinaryImageGroupData* imageGroup() const;
ClosureBuffer(const void* buff, size_t buffSize);
const CacheIdent& cacheIndent() const;
const char* targetPath() const;
uint32_t envVarCount() const;
void copyImageGroups(const char* envVars[]) const;
uint32_t imageGroupCount() const;
void copyImageGroups(const launch_cache::BinaryImageGroupData* imageGroups[]) const;
private:
enum { kindEnd=0, kindCacheIdent, kindTargetPath, kindEnvVar, kindImageGroup, kindClosure, kindErrorMessage };
static size_t computeSize(const char* path, const launch_cache::ImageGroupList& groups, const PathOverrides& envVars);
};
}
#endif // __DYLD_CLOSURE_BUFFER_H__