11ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/*
21ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Copyright (C) 2015 The Android Open Source Project
31ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *
41ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
51ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * you may not use this file except in compliance with the License.
61ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * You may obtain a copy of the License at
71ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *
81ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
91ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *
101ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Unless required by applicable law or agreed to in writing, software
111ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
121ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * See the License for the specific language governing permissions and
141ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * limitations under the License.
151ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */
161ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
174670805ea441edb8b280f9312571e7799f1284cfAdam Lesinski#ifndef AAPT_FORMAT_BINARY_CHUNKWRITER_H
184670805ea441edb8b280f9312571e7799f1284cfAdam Lesinski#define AAPT_FORMAT_BINARY_CHUNKWRITER_H
191ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
20ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "android-base/macros.h"
21ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "androidfw/ResourceTypes.h"
22ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
231ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/BigBuffer.h"
241ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/Util.h"
251ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
261ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskinamespace aapt {
271ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
281ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskiclass ChunkWriter {
29cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public:
304670805ea441edb8b280f9312571e7799f1284cfAdam Lesinski  explicit inline ChunkWriter(BigBuffer* buffer) : buffer_(buffer) {
314670805ea441edb8b280f9312571e7799f1284cfAdam Lesinski  }
32cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ChunkWriter(ChunkWriter&&) = default;
33cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ChunkWriter& operator=(ChunkWriter&&) = default;
34cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
35cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  template <typename T>
36ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  inline T* StartChunk(uint16_t type) {
37ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    start_size_ = buffer_->size();
38ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    T* chunk = buffer_->NextBlock<T>();
39ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    header_ = &chunk->header;
40ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    header_->type = util::HostToDevice16(type);
41ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    header_->headerSize = util::HostToDevice16(sizeof(T));
42cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return chunk;
43cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
44cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
45cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  template <typename T>
46ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  inline T* NextBlock(size_t count = 1) {
47ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    return buffer_->NextBlock<T>(count);
48cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
49cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
504670805ea441edb8b280f9312571e7799f1284cfAdam Lesinski  inline BigBuffer* buffer() {
514670805ea441edb8b280f9312571e7799f1284cfAdam Lesinski    return buffer_;
524670805ea441edb8b280f9312571e7799f1284cfAdam Lesinski  }
53cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
544670805ea441edb8b280f9312571e7799f1284cfAdam Lesinski  inline android::ResChunk_header* chunk_header() {
554670805ea441edb8b280f9312571e7799f1284cfAdam Lesinski    return header_;
564670805ea441edb8b280f9312571e7799f1284cfAdam Lesinski  }
57cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
584670805ea441edb8b280f9312571e7799f1284cfAdam Lesinski  inline size_t size() {
594670805ea441edb8b280f9312571e7799f1284cfAdam Lesinski    return buffer_->size() - start_size_;
604670805ea441edb8b280f9312571e7799f1284cfAdam Lesinski  }
61cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
62ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  inline android::ResChunk_header* Finish() {
63ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    buffer_->Align4();
64ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    header_->size = util::HostToDevice32(buffer_->size() - start_size_);
65ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    return header_;
66cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
67ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
68ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski private:
69ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  DISALLOW_COPY_AND_ASSIGN(ChunkWriter);
70ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
71ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  BigBuffer* buffer_;
72ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  size_t start_size_ = 0;
73ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  android::ResChunk_header* header_ = nullptr;
74cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski};
75cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
76cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinskitemplate <>
77ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiinline android::ResChunk_header* ChunkWriter::StartChunk(uint16_t type) {
78ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  start_size_ = buffer_->size();
79ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  header_ = buffer_->NextBlock<android::ResChunk_header>();
80ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  header_->type = util::HostToDevice16(type);
81ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  header_->headerSize = util::HostToDevice16(sizeof(android::ResChunk_header));
82ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  return header_;
831ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}
841ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
85cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski}  // namespace aapt
861ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
874670805ea441edb8b280f9312571e7799f1284cfAdam Lesinski#endif /* AAPT_FORMAT_BINARY_CHUNKWRITER_H */
88