Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(182)

Side by Side Diff: samples/myapi/generated/cc/struct.cc

Issue 1209033003: Work in progres, please take a look and give early feedback if this is the way we want to structure… (Closed) Base URL: git@github.com:dart-lang/fletch.git@master
Patch Set: address comments Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « samples/myapi/generated/cc/struct.h ('k') | samples/myapi/generated/cc/unicode.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE.md file.
4
5 #include "struct.h"
6
7 #include <stdlib.h>
8 #include <stddef.h>
9
10 #include "unicode.h"
11
12 static const int HEADER_SIZE = 56;
13
14 char* pointerToArgument(char* buffer, int offset) {
15 return buffer + HEADER_SIZE + offset;
16 }
17
18 int64_t* pointerToInt64Argument(char* buffer, int offset) {
19 return reinterpret_cast<int64_t*>(pointerToArgument(buffer, offset));
20 }
21
22 int64_t* pointerToResult(char* buffer) {
23 return pointerToInt64Argument(buffer, 0);
24 }
25
26 int64_t* pointerToSegments(char* buffer) {
27 return pointerToInt64Argument(buffer, -8);
28 }
29
30 void** pointerToCallbackFunction(char* buffer) {
31 return reinterpret_cast<void**>(pointerToArgument(buffer, -16));
32 }
33
34 void** pointerToCallbackData(char* buffer) {
35 return reinterpret_cast<void**>(pointerToArgument(buffer, -24));
36 }
37
38 MessageBuilder::MessageBuilder(int space)
39 : first_(this, 0, space),
40 last_(&first_),
41 segments_(1) {
42 }
43
44 int MessageBuilder::ComputeUsed() const {
45 int result = 0;
46 const BuilderSegment* current = &first_;
47 while (current != NULL) {
48 result += current->used();
49 current = current->next();
50 }
51 return result;
52 }
53
54 Builder MessageBuilder::InternalInitRoot(int size) {
55 // Return value and arguments use the same space. Therefore,
56 // the size of any struct needs to be at least 8 bytes in order
57 // to have room for the return address.
58 if (size == 0) size = 8;
59 int offset = first_.Allocate(HEADER_SIZE + size);
60 return Builder(&first_, offset + HEADER_SIZE);
61 }
62
63 BuilderSegment* MessageBuilder::FindSegmentForBytes(int bytes) {
64 if (last_->HasSpaceForBytes(bytes)) return last_;
65 int capacity = (bytes > 8192) ? bytes : 8192;
66 BuilderSegment* segment = new BuilderSegment(this, segments_++, capacity);
67 last_->set_next(segment);
68 last_ = segment;
69 return segment;
70 }
71
72 void MessageBuilder::DeleteMessage(char* buffer) {
73 int64_t segments = *pointerToSegments(buffer);
74 for (int i = 0; i < segments; i++) {
75 int64_t address = *pointerToInt64Argument(buffer, 8 + (i * 16));
76 char* memory = reinterpret_cast<char*>(address);
77 free(memory);
78 }
79 free(buffer);
80 }
81
82 MessageReader::MessageReader(int segments, char* memory)
83 : segment_count_(segments),
84 segments_(new Segment*[segments]) {
85 for (int i = 0; i < segments; i++) {
86 int64_t address = *reinterpret_cast<int64_t*>(memory + (i * 16));
87 int size = *reinterpret_cast<int*>(memory + 8 + (i * 16));
88 segments_[i] = new Segment(this, reinterpret_cast<char*>(address), size);
89 }
90 }
91
92 MessageReader::~MessageReader() {
93 for (int i = 0; i < segment_count_; ++i) {
94 delete segments_[i];
95 }
96 delete[] segments_;
97 }
98
99 Segment* MessageReader::GetRootSegment(char* memory) {
100 int32_t segments = *reinterpret_cast<int32_t*>(memory);
101 if (segments == 0) {
102 int32_t size = *reinterpret_cast<int32_t*>(memory + 4);
103 return new Segment(memory, size);
104 } else {
105 MessageReader* reader = new MessageReader(segments, memory + 8);
106 free(memory);
107 return new Segment(reader);
108 }
109 }
110
111 Segment::Segment(char* memory, int size)
112 : reader_(NULL),
113 memory_(memory),
114 size_(size),
115 is_root_(false) {
116 }
117
118 Segment::Segment(MessageReader* reader, char* memory, int size)
119 : reader_(reader),
120 memory_(memory),
121 size_(size),
122 is_root_(false) {
123 }
124
125 Segment::Segment(MessageReader* reader)
126 : reader_(reader),
127 is_root_(true) {
128 Segment* first = reader->GetSegment(0);
129 memory_ = first->memory();
130 size_ = first->size();
131 }
132
133 Segment::~Segment() {
134 if (is_root_) {
135 delete reader_;
136 } else {
137 free(memory_);
138 }
139 }
140
141 BuilderSegment::BuilderSegment(MessageBuilder* builder, int id, int capacity)
142 : Segment(reinterpret_cast<char*>(calloc(capacity, 1)), capacity),
143 builder_(builder),
144 id_(id),
145 next_(NULL),
146 used_(0) {
147 }
148
149 BuilderSegment::~BuilderSegment() {
150 if (next_ != NULL) {
151 delete next_;
152 next_ = NULL;
153 }
154 }
155
156 int BuilderSegment::Allocate(int bytes) {
157 if (!HasSpaceForBytes(bytes)) return -1;
158 int result = used_;
159 used_ += bytes;
160 return result;
161 }
162
163 void BuilderSegment::Detach() {
164 Segment::Detach();
165 if (next_ != NULL) next_->Detach();
166 }
167
168 static int ComputeStructBuffer(BuilderSegment* segment,
169 char** buffer) {
170 if (segment->HasNext()) {
171 // Build a segmented message. The segmented message has the
172 // usual 48-byte header, room for a result, and then a list
173 // of all the segments in the message. The segments in the
174 // message are extracted and freed on return from the service
175 // call.
176 int segments = segment->builder()->segments();
177 int size = HEADER_SIZE + 8 + (segments * 16);
178 *buffer = reinterpret_cast<char*>(malloc(size));
179 int offset = HEADER_SIZE + 8;
180 do {
181 *reinterpret_cast<void**>(*buffer + offset) = segment->At(0);
182 *reinterpret_cast<int*>(*buffer + offset + 8) = segment->used();
183 segment = segment->next();
184 offset += 16;
185 } while (segment != NULL);
186
187 // Mark the request as being segmented.
188 *pointerToSegments(*buffer) = segments;
189 return size;
190 }
191
192 *buffer = reinterpret_cast<char*>(segment->At(0));
193 int size = segment->used();
194 // Mark the request as being non-segmented.
195 *pointerToSegments(*buffer) = 0;
196 return size;
197 }
198
199 int64_t Builder::InvokeMethod(ServiceId service, MethodId method) {
200 BuilderSegment* segment = this->segment();
201 char* buffer;
202 int size = ComputeStructBuffer(segment, &buffer);
203 segment->Detach();
204 ServiceApiInvoke(service, method, buffer, size);
205 int64_t result = *pointerToResult(buffer);
206 MessageBuilder::DeleteMessage(buffer);
207 return result;
208 }
209
210 void Builder::InvokeMethodAsync(ServiceId service,
211 MethodId method,
212 ServiceApiCallback api_callback,
213 void* callback_function,
214 void* callback_data) {
215 BuilderSegment* segment = this->segment();
216 char* buffer;
217 int size = ComputeStructBuffer(segment, &buffer);
218 segment->Detach();
219 // Set the callback function (the user supplied callback).
220 *pointerToCallbackFunction(buffer) = callback_function;
221 *pointerToCallbackData(buffer) = callback_data;
222 ServiceApiInvokeAsync(service, method, api_callback, buffer, size);
223 }
224
225 Builder Builder::NewStruct(int offset, int size) {
226 offset += this->offset();
227 BuilderSegment* segment = this->segment();
228 while (true) {
229 int* lo = reinterpret_cast<int*>(segment->At(offset + 0));
230 int* hi = reinterpret_cast<int*>(segment->At(offset + 4));
231 int result = segment->Allocate(size);
232 if (result >= 0) {
233 *lo = (result << 2) | 1;
234 *hi = 0;
235 return Builder(segment, result);
236 }
237
238 BuilderSegment* other = segment->builder()->FindSegmentForBytes(size + 8);
239 int target = other->Allocate(8);
240 *lo = (target << 2) | 3;
241 *hi = other->id();
242
243 segment = other;
244 offset = target;
245 }
246 }
247
248 Reader Builder::NewList(int offset, int length, int size) {
249 offset += this->offset();
250 size *= length;
251 BuilderSegment* segment = this->segment();
252 while (true) {
253 int* lo = reinterpret_cast<int*>(segment->At(offset + 0));
254 int* hi = reinterpret_cast<int*>(segment->At(offset + 4));
255 int result = segment->Allocate(size);
256 if (result >= 0) {
257 *lo = (result << 2) | 2;
258 *hi = length;
259 return Reader(segment, result);
260 }
261
262 BuilderSegment* other = segment->builder()->FindSegmentForBytes(size + 8);
263 int target = other->Allocate(8);
264 *lo = (target << 2) | 3;
265 *hi = other->id();
266
267 segment = other;
268 offset = target;
269 }
270 }
271
272 void Builder::NewString(int offset, const char* value) {
273 size_t value_len = strlen(value);
274 Utf8::Type type;
275 intptr_t len = Utf8::CodeUnitCount(value, value_len, &type);
276 Reader reader = NewList(offset, len, 2);
277 uint16_t* dst =
278 reinterpret_cast<uint16_t*>(reader.segment()->memory() + reader.offset());
279 Utf8::DecodeToUTF16(value, value_len, dst, len);
280 }
281
282 int Reader::ComputeUsed() const {
283 MessageReader* reader = segment_->reader();
284 int used = 0;
285 for (int i = 0; i < reader->segment_count(); i++) {
286 used += reader->GetSegment(i)->size();
287 }
288 return used;
289 }
290
291 char* Reader::ReadString(int offset) const {
292 List<uint16_t> data = ReadList<uint16_t>(offset);
293 intptr_t len = Utf8::Length(data);
294 char* result = reinterpret_cast<char*>(malloc(len + 1));
295 Utf8::Encode(data, result, len);
296 result[len] = 0;
297 return result;
298 }
OLDNEW
« no previous file with comments | « samples/myapi/generated/cc/struct.h ('k') | samples/myapi/generated/cc/unicode.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698