00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <errno.h>
00027 #include <string.h>
00028 #include <stdlib.h>
00029 #include "buffer.h"
00030 #include "buffer_internal.h"
00031 #include "buffer_util.h"
00032 #include "data_object.h"
00033 #include "data_object_memory.h"
00034 #include "type_limits.h"
00035 #include "buffer_action.h"
00036 #include "buffer_action_edit.h"
00037 #include "buffer_event.h"
00038 #include "util.h"
00039 #include "debug.h"
00040
00041 #pragma GCC visibility push(default)
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 static int read_foreach_func(segcol_t *segcol, segment_t *seg,
00060 off_t mapping, off_t read_start, off_t read_length, void *user_data)
00061 {
00062 UNUSED_PARAM(segcol);
00063 UNUSED_PARAM(mapping);
00064
00065 data_object_t *dobj;
00066 segment_get_data(seg, (void **)&dobj);
00067
00068
00069 unsigned char **dst = (unsigned char **)user_data;
00070
00071 int err = read_data_object(dobj, read_start, *dst, read_length);
00072 if (err)
00073 return_error(err);
00074
00075
00076 *dst += read_length;
00077
00078 return 0;
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 int bless_buffer_append(bless_buffer_t *buf, bless_buffer_source_t *src,
00096 off_t src_offset, off_t length)
00097 {
00098 if (buf == NULL || src == NULL)
00099 return_error(EINVAL);
00100
00101 buffer_action_t *action;
00102 struct bless_buffer_event_info event_info;
00103
00104
00105 int err = buffer_action_append_new(&action, buf, src, src_offset, length);
00106 if (err)
00107 return_error(err);
00108
00109
00110 err = buffer_action_do(action);
00111 if (err) {
00112 buffer_action_free(action);
00113 return_error(err);
00114 }
00115
00116
00117
00118
00119
00120 if (buf->multi_action_mode) {
00121
00122 if (buf->multi_action != NULL) {
00123 err = buffer_action_multi_add(buf->multi_action, action);
00124 if (err)
00125 goto fail;
00126 }
00127 else
00128 buffer_action_free(action);
00129
00130 return 0;
00131 }
00132
00133
00134 err = buffer_action_to_event(action, &event_info);
00135 if (err)
00136 goto fail;
00137
00138
00139
00140
00141
00142 err = undo_list_enforce_limit(buf, 1);
00143 if (err)
00144 goto fail;
00145
00146
00147
00148
00149
00150 if (buf->undo_list_size < buf->options->undo_limit) {
00151 err = undo_list_append(buf, action);
00152 if (err)
00153 goto fail;
00154 }
00155 else
00156 buffer_action_free(action);
00157
00158 action_list_clear(buf->redo_list);
00159 buf->redo_list_size = 0;
00160
00161
00162 if (buf->event_func != NULL) {
00163 event_info.event_type = BLESS_BUFFER_EVENT_EDIT;
00164 (*buf->event_func)(buf, &event_info, buf->event_user_data);
00165 }
00166
00167 return 0;
00168
00169 fail:
00170 buffer_action_undo(action);
00171 buffer_action_free(action);
00172 return_error(err);
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 int bless_buffer_insert(bless_buffer_t *buf, off_t offset,
00187 bless_buffer_source_t *src, off_t src_offset, off_t length)
00188 {
00189 if (buf == NULL || src == NULL)
00190 return_error(EINVAL);
00191
00192
00193 buffer_action_t *action;
00194 struct bless_buffer_event_info event_info;
00195
00196 int err = buffer_action_insert_new(&action, buf, offset, src, src_offset,
00197 length);
00198
00199 if (err)
00200 return_error(err);
00201
00202
00203 err = buffer_action_do(action);
00204 if (err) {
00205 buffer_action_free(action);
00206 return_error(err);
00207 }
00208
00209
00210
00211
00212
00213 if (buf->multi_action_mode) {
00214
00215 if (buf->multi_action != NULL) {
00216 err = buffer_action_multi_add(buf->multi_action, action);
00217 if (err)
00218 goto fail;
00219 }
00220 else
00221 buffer_action_free(action);
00222
00223 return 0;
00224 }
00225
00226
00227 err = buffer_action_to_event(action, &event_info);
00228 if (err)
00229 goto fail;
00230
00231
00232
00233
00234
00235 err = undo_list_enforce_limit(buf, 1);
00236 if (err)
00237 goto fail;
00238
00239
00240
00241
00242
00243 if (buf->undo_list_size < buf->options->undo_limit) {
00244 err = undo_list_append(buf, action);
00245 if (err)
00246 goto fail;
00247 }
00248 else
00249 buffer_action_free(action);
00250
00251 action_list_clear(buf->redo_list);
00252 buf->redo_list_size = 0;
00253
00254
00255 if (buf->event_func != NULL) {
00256 event_info.event_type = BLESS_BUFFER_EVENT_EDIT;
00257 (*buf->event_func)(buf, &event_info, buf->event_user_data);
00258 }
00259
00260 return 0;
00261
00262 fail:
00263 buffer_action_undo(action);
00264 buffer_action_free(action);
00265 return_error(err);
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 int bless_buffer_delete(bless_buffer_t *buf, off_t offset, off_t length)
00278 {
00279 if (buf == NULL)
00280 return_error(EINVAL);
00281
00282
00283 buffer_action_t *action;
00284 struct bless_buffer_event_info event_info;
00285
00286 int err = buffer_action_delete_new(&action, buf, offset, length);
00287
00288 if (err)
00289 return_error(err);
00290
00291
00292 err = buffer_action_do(action);
00293 if (err) {
00294 buffer_action_free(action);
00295 return_error(err);
00296 }
00297
00298
00299
00300
00301
00302 if (buf->multi_action_mode) {
00303
00304 if (buf->multi_action != NULL) {
00305 err = buffer_action_multi_add(buf->multi_action, action);
00306 if (err)
00307 goto fail;
00308 }
00309 else
00310 buffer_action_free(action);
00311
00312 return 0;
00313 }
00314
00315
00316 err = buffer_action_to_event(action, &event_info);
00317 if (err)
00318 goto fail;
00319
00320
00321
00322
00323
00324 err = undo_list_enforce_limit(buf, 1);
00325 if (err)
00326 goto fail;
00327
00328
00329
00330
00331
00332 if (buf->undo_list_size < buf->options->undo_limit) {
00333 err = undo_list_append(buf, action);
00334 if (err)
00335 goto fail;
00336 }
00337 else
00338 buffer_action_free(action);
00339
00340 action_list_clear(buf->redo_list);
00341 buf->redo_list_size = 0;
00342
00343
00344 if (buf->event_func != NULL) {
00345 event_info.event_type = BLESS_BUFFER_EVENT_EDIT;
00346 (*buf->event_func)(buf, &event_info, buf->event_user_data);
00347 }
00348
00349 return 0;
00350
00351 fail:
00352 buffer_action_undo(action);
00353 buffer_action_free(action);
00354 return_error(err);
00355 }
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 int bless_buffer_read(bless_buffer_t *buf, off_t src_offset, void *dst,
00369 size_t dst_offset, size_t length)
00370 {
00371 if (buf == NULL || src_offset < 0 || dst == NULL)
00372 return_error(EINVAL);
00373
00374
00375
00376
00377
00378 if (__MAX(size_t) - (size_t)dst < dst_offset)
00379 return_error(EOVERFLOW);
00380
00381 if (__MAX(size_t) - (size_t)dst - dst_offset < length - 1 * (length != 0))
00382 return_error(EOVERFLOW);
00383
00384 void *cur_dst = (unsigned char *)dst + dst_offset;
00385
00386 int err = segcol_foreach(buf->segcol, src_offset, length,
00387 read_foreach_func, &cur_dst);
00388 if (err)
00389 return_error(err);
00390
00391 return 0;
00392 }
00393
00394
00395 #pragma GCC visibility push(hidden)
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408 int bless_buffer_copy(bless_buffer_t *src, off_t src_offset, bless_buffer_t *dst,
00409 off_t dst_offset, off_t length)
00410 {
00411 UNUSED_PARAM(src);
00412 UNUSED_PARAM(src_offset);
00413 UNUSED_PARAM(dst);
00414 UNUSED_PARAM(dst_offset);
00415 UNUSED_PARAM(length);
00416
00417 return_error(ENOSYS);
00418 }
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434 int bless_buffer_find(bless_buffer_t *buf, off_t *match, off_t start_offset,
00435 void *data, size_t length, bless_progress_func *progress_func)
00436 {
00437 UNUSED_PARAM(buf);
00438 UNUSED_PARAM(match);
00439 UNUSED_PARAM(start_offset);
00440 UNUSED_PARAM(data);
00441 UNUSED_PARAM(length);
00442 UNUSED_PARAM(progress_func);
00443
00444 return_error(ENOSYS);
00445 }
00446
00447 #pragma GCC visibility pop
00448
00449 #pragma GCC visibility pop
00450