@@ -81,6 +81,7 @@ struct viewport_t {
81
81
on_change_cbk cbk{};
82
82
void *user_data_ptr{};
83
83
vector<uint8_t > data;
84
+ uint8_t bit_offset{};
84
85
};
85
86
86
87
const author_t *get_viewport_author (const viewport_t *viewport_ptr) {
@@ -107,20 +108,62 @@ void *get_viewport_user_data(const viewport_t *viewport_ptr) {
107
108
return viewport_ptr->user_data_ptr ;
108
109
}
109
110
111
+ uint8_t get_viewport_bit_offset (const viewport_t *viewport_ptr) {
112
+ return viewport_ptr->bit_offset ;
113
+ }
114
+
115
+ typedef vector<shared_ptr<author_t > > author_vector_t ;
116
+ typedef vector<shared_ptr<viewport_t > > viewport_vector_t ;
117
+ typedef vector<change_t > change_vector_t ;
118
+
110
119
struct session_t {
111
120
FILE *file_ptr{};
112
121
int64_t serial{};
113
122
int64_t computed_file_size{};
114
- vector<shared_ptr< author_t > > authors;
115
- vector<shared_ptr< viewport_t > > viewports;
116
- vector< change_t > changes;
123
+ author_vector_t authors;
124
+ viewport_vector_t viewports;
125
+ change_vector_t changes;
117
126
vector<int64_t > changes_by_offset;
118
127
};
119
128
120
129
//
121
130
// FUNCTIONS
122
131
//
123
132
133
+ int left_shift_buffer (uint8_t *array, int64_t len, uint8_t shift_left) {
134
+ int rc = -1 ;
135
+ if (shift_left > 0 && shift_left < 8 ) {
136
+ uint8_t shift_right = 8 - shift_left;
137
+ uint8_t mask = ((1 << shift_left) - 1 ) << shift_right;
138
+ uint8_t bits1 = 0 ;
139
+ for (auto i = len - 1 ; i >= 0 ; --i) {
140
+ auto bits2 = array[i] & mask;
141
+ array[i] <<= shift_left;
142
+ array[i] |= bits1 >> shift_right;
143
+ bits1 = bits2;
144
+ }
145
+ rc = 0 ;
146
+ }
147
+ return rc;
148
+ }
149
+
150
+ int right_shift_buffer (uint8_t *array, int64_t len, uint8_t shift_right) {
151
+ int rc = -1 ;
152
+ if (shift_right > 0 && shift_right < 8 ) {
153
+ uint8_t shift_left = 8 - shift_right;
154
+ uint8_t mask = (1 << shift_right) - 1 ;
155
+ uint8_t bits1 = 0 ;
156
+ for (auto i = len - 1 ; i >= 0 ; --i) {
157
+ auto bits2 = array[i] & mask;
158
+ array[i] >>= shift_right;
159
+ array[i] |= bits1 << shift_left;
160
+ bits1 = bits2;
161
+ }
162
+ rc = 0 ;
163
+ }
164
+ return rc;
165
+ }
166
+
124
167
session_t *create_session (FILE *file_ptr) {
125
168
fseek (file_ptr, 0L , SEEK_END);
126
169
auto *session_ptr = new session_t ;
@@ -147,7 +190,8 @@ session_t *get_author_session(const author_t *author_ptr) {
147
190
}
148
191
149
192
viewport_t *
150
- add_viewport (const author_t *author_ptr, int64_t offset, int32_t capacity, on_change_cbk cbk, void *user_data_ptr) {
193
+ add_viewport (const author_t *author_ptr, int64_t offset, int32_t capacity, on_change_cbk cbk, void *user_data_ptr,
194
+ uint8_t bit_offset) {
151
195
auto viewport_ptr = shared_ptr<viewport_t >(new viewport_t );
152
196
viewport_ptr->author_ptr = author_ptr;
153
197
viewport_ptr->computed_offset = offset;
@@ -156,31 +200,52 @@ add_viewport(const author_t *author_ptr, int64_t offset, int32_t capacity, on_ch
156
200
viewport_ptr->data .reserve (capacity);
157
201
viewport_ptr->cbk = cbk;
158
202
viewport_ptr->user_data_ptr = user_data_ptr;
203
+ viewport_ptr->bit_offset = bit_offset;
159
204
author_ptr->session_ptr ->viewports .push_back (viewport_ptr);
160
205
// TODO: populate the viewport and call the on change callback
161
206
read_segment (author_ptr->session_ptr ->file_ptr , offset, author_ptr->session_ptr ->computed_file_size ,
162
207
viewport_ptr->data .data (), viewport_ptr->capacity ,
163
- &viewport_ptr->length );
208
+ &viewport_ptr->length , viewport_ptr-> bit_offset );
164
209
(*viewport_ptr->cbk )(viewport_ptr.get (), nullptr );
165
210
return viewport_ptr.get ();
166
211
}
167
212
168
- int set_viewport (viewport_t *viewport_ptr, int64_t offset, int32_t capacity) {
213
+ int destroy_viewport (const viewport_t *viewport_ptr) {
214
+ int rc = -1 ;
215
+ viewport_vector_t *session_viewport_ptr = &viewport_ptr->author_ptr ->session_ptr ->viewports ;
216
+ for (auto iter = session_viewport_ptr->begin (); iter != session_viewport_ptr->end (); ++iter) {
217
+ if (viewport_ptr == iter->get ()) {
218
+ session_viewport_ptr->erase (iter);
219
+ rc = 0 ;
220
+ break ;
221
+ }
222
+ }
223
+ return rc;
224
+ }
225
+
226
+ int set_viewport (viewport_t *viewport_ptr, int64_t offset, int32_t capacity, uint8_t bit_offset) {
169
227
// only change settings if they are different
170
- if (viewport_ptr->computed_offset != offset || viewport_ptr->capacity != capacity) {
228
+ if (viewport_ptr->computed_offset != offset || viewport_ptr->capacity != capacity ||
229
+ viewport_ptr->bit_offset != bit_offset) {
171
230
viewport_ptr->computed_offset = offset;
172
231
viewport_ptr->capacity = capacity;
173
232
viewport_ptr->data .reserve (capacity);
233
+ viewport_ptr->bit_offset = bit_offset;
174
234
// TODO: update viewport and call the on change callback
175
235
read_segment (viewport_ptr->author_ptr ->session_ptr ->file_ptr , offset,
176
236
viewport_ptr->author_ptr ->session_ptr ->computed_file_size , viewport_ptr->data .data (),
177
237
viewport_ptr->capacity ,
178
- &viewport_ptr->length );
238
+ &viewport_ptr->length ,
239
+ viewport_ptr->bit_offset );
179
240
(*viewport_ptr->cbk )(viewport_ptr, nullptr );
180
241
}
181
242
return 0 ;
182
243
}
183
244
245
+ size_t num_viewports (const session_t *session_ptr) {
246
+ return session_ptr->viewports .size ();
247
+ }
248
+
184
249
// Internal function to add a change to the given session
185
250
int add_change_ (const change_t *change_ptr) {
186
251
auto session_ptr = change_ptr->author_ptr ->session_ptr ;
@@ -286,12 +351,15 @@ size_t num_changes_by_author(const author_t *author_ptr) {
286
351
}
287
352
288
353
int read_segment (FILE *from_file_ptr, int64_t offset, int64_t file_size, uint8_t *buffer, int64_t capacity,
289
- int64_t *length) {
354
+ int64_t *length, uint8_t bit_offset ) {
290
355
auto len = file_size - offset;
291
356
if (len > 0 ) {
292
357
*length = (len < capacity) ? len : capacity;
293
358
fseek (from_file_ptr, offset, SEEK_SET);
294
359
fread (buffer, 1 , *length, from_file_ptr);
360
+ if (bit_offset > 0 ) {
361
+ left_shift_buffer (buffer, *length, bit_offset);
362
+ }
295
363
}
296
364
return 0 ;
297
365
}
@@ -368,11 +436,6 @@ int save(const author_t *author_ptr, FILE *file_ptr) {
368
436
return 0 ;
369
437
}
370
438
371
- viewport_t *add_viewport (const author_t *author_ptr, int32_t capacity, on_change_cbk cbk, void *user_data_ptr) {
372
- // TODO: Implement
373
- return nullptr ;
374
- }
375
-
376
439
// returns 1 if a change was found and undone and 0 if no change was found
377
440
int undo (const author_t *author_ptr) {
378
441
int rc = 0 ;
0 commit comments