blob: 47803a439c11979de0759919f1149fbbb04bb8e5 [file] [log] [blame]
/* Copyright 2016 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __IMAGE_HH__
#define __IMAGE_HH__
#include <cassert>
#include <memory>
#include <string>
#include "dcdir_structs.h"
#include "region.hh"
namespace dcdir
{
class ImageBuffer
{
public:
// The image initializes itself with the file at file_name.
explicit ImageBuffer(const std::string &file_name);
// Return a pointer to the buffer holding the image's contents.
void *buf() const
{
return buf_.get();
}
// Return the size of the image.
uint32_t size() const
{
return size_;
}
// Mark the image as modified in case it needs to be written back.
void modified(bool new_modified)
{
modified_ = new_modified;
}
// Return the major version number.
int major_version() const
{
return major_version_;
}
// Return the minor version number.
int minor_version() const
{
return minor_version_;
}
// Return the number of bytes occupied by the dcdir structures
// themselves.
size_t storage_overhead() const;
// Return a pointer to the root directory in this image.
dcdir::Region *root_dir() const
{
return root_dir_.get();
}
/*
* Given a pointer into the image's buffer, return the offset of that
* data in bytes. Also check that the type pointed to fits entirely
* within the image.
*/
template<typename T>
uint32_t offset_of(const T *ptr) const
{
uint32_t ret = (const uint8_t *)ptr -
(const uint8_t *)buf_.get();
assert(ret + sizeof(T) <= size_);
return ret;
}
/*
* Given an offset into the image, return a pointer to that data. Also
* make sure that the type pointed to fits within the buffer. The
* pointer is set by reference so that the template knows what type
* to use without having to have a clunky <> at each call sight.
*/
template<typename T>
void pointer_to(uint32_t off, T *&ptr) const
{
assert(off + sizeof(T) <= size_);
ptr = (T*)((uint8_t *)buf_.get() + off);
}
private:
DcDirAnchor *find_anchor();
// Buffer of image data.
std::unique_ptr<uint8_t []> buf_;
// Size of the image/data.
uint32_t size_;
// Whether the image data has been changed and should be written back,
// if that's appropriate for what the user requested.
bool modified_;
// Version numbers of the dcdir structures.
int major_version_;
int minor_version_;
// The root directory in this image.
std::unique_ptr<Region> root_dir_;
};
} // namespace dcdir
#endif // __IMAGE_HH__