00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include <jf/jf_config.h>
00021
00022
00023
00024
#ifdef HAVE_STDIO_H
00025
# include <stdio.h>
00026
#endif
00027
#ifdef HAVE_STDLIB_H
00028
# include <stdlib.h>
00029
#endif
00030
#ifdef HAVE_STRING_H
00031
# include <string.h>
00032
#endif
00033
#ifdef HAVE_STDARG_H
00034
# include <stdarg.h>
00035
#endif
00036
#ifdef HAVE_ERRNO_H
00037
# include <errno.h>
00038
#endif
00039
00040
#include <jf/jf_errors.h>
00041
#include <jf/jf_trace.h>
00042
#include <jf_file.h>
00043
00044
00045
00046
00047
#ifdef JF_TRACE_MODULE
00048
# undef JF_TRACE_MODULE
00049
#endif
00050 #define JF_TRACE_MODULE JF_TRACE_MOD_LIB_FILE
00051
00052
00053
00054 void jf_file_reset(
jf_file_t *jf)
00055 {
00056
JF_TRACE((
"jf_file_reset\n"));
00057 jf->
journal = NULL;
00058 jf->
private_journal =
FALSE;
00059 jf->
id =
JF_JOURNAL_GLOBAL_FILE_ID;
00060 jf->
char_buffer = NULL;
00061 jf->
char_buffer_size = 0;
00062 }
00063
00064
00065
00066 int jf_file_open(
jf_file_t *jfile,
jf_journal_t *journal,
00067
const char *path,
const char *mode,
00068
const struct jf_file_open_opts_s *options)
00069 {
00070
enum Exception { INVALID_PATH
00071 , MALLOC_NAME
00072 , MALLOC_JOURNAL
00073 , JOURNAL_OPEN
00074 , JOURNAL_OPEN_ATTACH_FILE
00075 , NONE } excp;
00076
int ret_cod =
JF_RC_INTERNAL_ERROR;
00077
00078
char *journal_path = NULL;
00079
00080
JF_TRACE((
"jf_file_open\n"));
00081 TRY {
00082
const struct jf_journal_file_opts_s *journal_file_opts = NULL;
00083
struct jf_file_open_opts_s opts;
00084
int join_the_journal =
TRUE;
00085
00086
if (NULL != options)
00087 opts = *options;
00088
else
00089
jf_set_default_file_open_opts(&opts);
00090
00091
if (path == NULL || strlen(path) == 0)
00092
THROW(INVALID_PATH);
00093
00094
00095
jf_file_reset(jfile);
00096
00097
if (NULL == journal) {
00098
00099
if (NULL == (journal_path = (
char *)malloc(
00100 strlen(path) +
00101 strlen(
JF_JOURNAL_EXTENSION)+1)))
00102
THROW(MALLOC_NAME);
00103 strcpy(journal_path, path);
00104 strcat(journal_path,
JF_JOURNAL_EXTENSION);
00105
00106
00107 jfile->
private_journal =
TRUE;
00108
if (NULL == (jfile->
journal = (
jf_journal_t *)malloc(
00109
sizeof(
jf_journal_t))))
00110
THROW(MALLOC_JOURNAL);
00111
00112 opts.
journal_opts.
flags |=
00113
JF_JOURNAL_PROP_OPEN_O_CREAT;
00114
00115 ret_cod =
jf_journal_open(
00116 jfile->
journal, journal_path, 1,
00117 &(opts.
journal_opts));
00118
if (
JF_RC_OK != ret_cod)
00119
THROW(JOURNAL_OPEN);
00120 }
else {
00121 jfile->
private_journal =
FALSE;
00122 jfile->
journal = journal;
00123 }
00124
00125
if (options != NULL) {
00126 join_the_journal = opts.
join_the_journal;
00127 }
00128 journal_file_opts = &(opts.
journal_opts.
journal_file_opts);
00129
00130
00131 ret_cod =
jf_journal_open_attach_file(
00132 jfile->
journal, path, mode, &(jfile->
id),
00133 join_the_journal, journal_file_opts);
00134
if (
JF_RC_OK != ret_cod)
00135
THROW(JOURNAL_OPEN_ATTACH_FILE);
00136
00137
THROW(NONE);
00138 }
CATCH {
00139
switch (excp) {
00140
case INVALID_PATH:
00141 ret_cod =
JF_RC_INVALID_PATH_NAME;
00142
break;
00143
case MALLOC_NAME:
00144 ret_cod =
JF_RC_MALLOC_ERROR;
00145
break;
00146
case MALLOC_JOURNAL:
00147 ret_cod =
JF_RC_MALLOC_ERROR;
00148
break;
00149
case JOURNAL_OPEN:
00150
break;
00151
case JOURNAL_OPEN_ATTACH_FILE:
00152
break;
00153
case NONE:
00154 ret_cod =
JF_RC_OK;
00155
break;
00156
default:
00157 ret_cod =
JF_RC_INTERNAL_ERROR;
00158 }
00159
00160
00161
if (NULL != journal_path)
00162 free(journal_path);
00163
00164
00165
if (excp > MALLOC_JOURNAL && excp < NONE) {
00166
if (journal == NULL && jfile->
journal != NULL)
00167 free(jfile->
journal);
00168 jfile->
journal = NULL;
00169 }
00170
00171 }
00172
JF_TRACE((
"jf_file_open/excp=%d/ret_cod=%d/errno=%d\n",
00173 excp, ret_cod, errno));
00174
return ret_cod;
00175 }
00176
00177
00178
00179 int jf_file_check_mode(
const char *mode, uint32_t *flags)
00180 {
00181
enum Exception { INVALID_POINTER
00182 , INVALID_FIRST
00183 , INVALID_SECOND
00184 , INVALID_THIRD
00185 , NONE } excp;
00186
int ret_cod =
JF_RC_INTERNAL_ERROR;
00187
00188 uint32_t tmp_flags = 0;
00189
00190
JF_TRACE((
"jf_file_check_mode\n"));
00191 TRY {
00192
if (mode == NULL)
00193
THROW(INVALID_POINTER);
00194
00195
00196
switch (mode[0]) {
00197
case 'r':
00198 tmp_flags |=
JF_FILE_OM_READ;
00199
break;
00200
case 'R':
00201 tmp_flags |=
JF_FILE_OM_READ |
JF_FILE_OM_RESTART;
00202
break;
00203
case 'w':
00204 tmp_flags |=
JF_FILE_OM_WRITE |
JF_FILE_OM_TRUNCATE;
00205
break;
00206
case 'W':
00207 tmp_flags |=
JF_FILE_OM_WRITE |
JF_FILE_OM_RESTART |
00208
JF_FILE_OM_TRUNCATE;
00209
break;
00210
case 'a':
00211 tmp_flags |=
JF_FILE_OM_WRITE |
JF_FILE_OM_APPEND;
00212
break;
00213
default:
00214
THROW(INVALID_FIRST);
00215 }
00216
00217
00218
switch (mode[1]) {
00219
case '\0':
00220
THROW(NONE);
00221
case 'D':
00222 tmp_flags |=
JF_FILE_OM_MSDOS;
00223
break;
00224
case '+':
00225 tmp_flags |=
JF_FILE_OM_READ |
JF_FILE_OM_WRITE;
00226
break;
00227
default:
00228
THROW(INVALID_SECOND);
00229 }
00230
00231
00232
switch (mode[2]) {
00233
case '\0':
00234
THROW(NONE);
00235
case 'D':
00236 tmp_flags |=
JF_FILE_OM_MSDOS;
00237
break;
00238
case '+':
00239 tmp_flags |=
JF_FILE_OM_READ |
JF_FILE_OM_WRITE;
00240
break;
00241
default:
00242
THROW(INVALID_THIRD);
00243 }
00244
00245
THROW(NONE);
00246 }
CATCH {
00247
switch (excp) {
00248
case INVALID_POINTER:
00249 ret_cod =
JF_RC_NULL_OBJECT;
00250
break;
00251
case INVALID_FIRST:
00252
00253
case INVALID_SECOND:
00254
00255
case INVALID_THIRD:
00256 ret_cod =
JF_RC_INVALID_OPTION;
00257
break;
00258
case NONE:
00259 *flags = tmp_flags;
00260 ret_cod =
JF_RC_OK;
00261
break;
00262
default:
00263 ret_cod =
JF_RC_INTERNAL_ERROR;
00264 }
00265 }
00266
JF_TRACE((
"jf_file_check_mode/excp=%d/ret_cod=%d\n",
00267 excp, ret_cod));
00268
return ret_cod;
00269 }
00270
00271
00272
00273 int jf_file_build_open_mode(uint32_t flags,
char *mode1,
char *mode2,
00274
int *repos,
int *resize,
int *append)
00275 {
00276
enum Exception { UNSUPPORTED_MODE
00277 , NONE } excp;
00278
int ret_cod =
JF_RC_INTERNAL_ERROR;
00279
00280
JF_TRACE((
"jf_file_build_open_mode\n"));
00281 TRY {
00282
00283 uint32_t tmp_flags = flags &
00284 (
JF_FILE_OM_MASK & (~
JF_FILE_OM_MSDOS));
00285
00286
00287 *repos =
FALSE;
00288 *resize =
FALSE;
00289 *append =
FALSE;
00290
00291
00292 *mode1 =
'\0';
00293 *mode2 =
'\0';
00294
00295
00296
00297
00298
switch (tmp_flags) {
00299
case JF_FILE_OM_READ:
00300
00301 strcpy(mode1,
"rb");
00302
break;
00303
case JF_FILE_OM_READ |
JF_FILE_OM_WRITE:
00304
00305 strcpy(mode1,
"r+b");
00306
break;
00307
case JF_FILE_OM_READ |
JF_FILE_OM_RESTART:
00308
00309 *repos =
TRUE;
00310 strcpy(mode1,
"rb");
00311
break;
00312
case JF_FILE_OM_READ |
JF_FILE_OM_WRITE |
00313
JF_FILE_OM_RESTART:
00314
00315 *repos =
TRUE;
00316 strcpy(mode1,
"r+b");
00317
break;
00318
case JF_FILE_OM_WRITE |
JF_FILE_OM_TRUNCATE:
00319
00320 *resize =
TRUE;
00321 strcpy(mode1,
"r+b");
00322 strcpy(mode2,
"wb");
00323
break;
00324
case JF_FILE_OM_WRITE |
JF_FILE_OM_READ |
00325
JF_FILE_OM_TRUNCATE:
00326
00327 *resize =
TRUE;
00328 strcpy(mode1,
"r+b");
00329 strcpy(mode2,
"w+b");
00330
break;
00331
case JF_FILE_OM_WRITE |
JF_FILE_OM_TRUNCATE |
00332
JF_FILE_OM_RESTART:
00333
00334 *repos =
TRUE;
00335 *resize =
TRUE;
00336 strcpy(mode1,
"r+b");
00337 strcpy(mode2,
"wb");
00338
break;
00339
case JF_FILE_OM_WRITE |
JF_FILE_OM_READ |
00340
JF_FILE_OM_TRUNCATE |
JF_FILE_OM_RESTART:
00341
00342 *repos =
TRUE;
00343 *resize =
TRUE;
00344 strcpy(mode1,
"r+b");
00345 strcpy(mode2,
"w+b");
00346
break;
00347
case JF_FILE_OM_WRITE |
JF_FILE_OM_APPEND:
00348
00349 *append =
TRUE;
00350 strcpy(mode1,
"r+b");
00351 strcpy(mode2,
"wb");
00352
break;
00353
case JF_FILE_OM_WRITE |
JF_FILE_OM_READ |
00354
JF_FILE_OM_APPEND:
00355
00356 *append =
TRUE;
00357 strcpy(mode1,
"r+b");
00358 strcpy(mode2,
"w+b");
00359
break;
00360
default:
00361
THROW(UNSUPPORTED_MODE);
00362 }
00363
00364
THROW(NONE);
00365 }
CATCH {
00366
switch (excp) {
00367
case UNSUPPORTED_MODE:
00368 ret_cod =
JF_RC_INVALID_OPTION;
00369
break;
00370
case NONE:
00371 ret_cod =
JF_RC_OK;
00372
break;
00373
default:
00374 ret_cod =
JF_RC_INTERNAL_ERROR;
00375 }
00376 }
00377
JF_TRACE((
"jf_file_build_open_mode/excp=%d/ret_cod=%d\n",
00378 excp, ret_cod));
00379
return ret_cod;
00380 }
00381
00382
00383
00384 int jf_file_close(
jf_file_t *jfile)
00385 {
00386
enum Exception { NOT_SAFE
00387 , INVALID_BUFFER
00388 , ROLLBACK
00389 , JOURNAL_CLOSE_DETACH_FILE
00390 , JOURNAL_CLOSE
00391 , NONE } excp;
00392
int ret_cod =
JF_RC_INTERNAL_ERROR;
00393
00394
JF_TRACE((
"jf_file_close\n"));
00395 TRY {
00396
00397
if (!
jf_file_is_safe(jfile))
00398
THROW(NOT_SAFE);
00399
00400
#ifdef _EXTRA_CHECK
00401
if ((NULL == jfile->
char_buffer &&
00402 0 != jfile->
char_buffer_size) ||
00403 (NULL != jfile->
char_buffer &&
00404 0 == jfile->
char_buffer_size))
00405
THROW(INVALID_BUFFER);
00406
#endif
00407
00408
if (NULL != jfile->
char_buffer) {
00409 free(jfile->
char_buffer);
00410 jfile->
char_buffer = NULL;
00411 jfile->
char_buffer_size = 0;
00412 }
00413
00414
00415
if (
JF_RC_OK != (ret_cod =
jf_file_rollback(jfile)))
00416
THROW(ROLLBACK);
00417
00418
00419
if (
JF_RC_OK != (ret_cod =
jf_journal_close_detach_file(
00420 jfile->
journal, jfile->
id)))
00421
THROW(JOURNAL_CLOSE_DETACH_FILE);
00422
00423
00424
if (jfile->
private_journal &&
00425
JF_RC_OK != (ret_cod =
jf_journal_close(jfile->
journal)))
00426
THROW(JOURNAL_CLOSE);
00427
00428
00429
jf_file_reset(jfile);
00430
00431
THROW(NONE);
00432 }
CATCH {
00433
switch (excp) {
00434
case NOT_SAFE:
00435 ret_cod =
JF_RC_OBJ_CORRUPTED;
00436
break;
00437
#ifdef _EXTRA_CHECK
00438
case INVALID_BUFFER:
00439 ret_cod =
JF_RC_INVALID_STATUS;
00440
break;
00441
#endif
00442
case ROLLBACK:
00443
case JOURNAL_CLOSE_DETACH_FILE:
00444
case JOURNAL_CLOSE:
00445
break;
00446
case NONE:
00447 ret_cod =
JF_RC_OK;
00448
break;
00449
default:
00450 ret_cod =
JF_RC_INTERNAL_ERROR;
00451 }
00452 }
00453
JF_TRACE((
"jf_file_close/excp=%d/ret_cod=%d/errno=%d\n",
00454 excp, ret_cod, errno));
00455
return ret_cod;
00456 }
00457
00458
00459
00460 jf_offset_t jf_file_get_cache_limit(
const jf_file_t *jfile)
00461 {
00462
jf_journal_file_t *jf;
00463
jf_cache_file_t *cf;
00464
00465
if (!
jf_file_is_safe(jfile))
00466
return -1;
00467
if (NULL == (jf =
jf_journal_get_jfile(
00468 jfile->
journal, jfile->
id)))
00469
return -1;
00470
if (NULL == (cf =
jf_journal_file_get_cache_file(jf)))
00471
return -1;
00472
return jf_cache_file_get_limit(cf);
00473 }
00474
00475
00476
00477 int jf_file_seek(
jf_file_t *jf,
jf_offset_t offset,
int whence)
00478 {
00479
enum Exception { OBJ_NOT_SAFE
00480 , NOTHING_TO_DO
00481 , INVALID_WHENCE_VALUE
00482 , INVALID_OFFSET
00483 , SET_LAST_UC_POS
00484 , NONE } excp;
00485
int ret_cod =
JF_RC_INTERNAL_ERROR;
00486
00487
JF_TRACE((
"jf_file_seek\n"));
00488 TRY {
00489
jf_journal_t *journal;
00490
jf_word_t file_id;
00491
jf_journal_file_t *jfp;
00492
jf_offset_t tmp_off;
00493 uint32_t open_mode;
00494
00495
if (!
jf_file_is_safe(jf))
00496
THROW(OBJ_NOT_SAFE);
00497
00498 journal =
jf_file_get_journal(jf);
00499 file_id =
jf_file_get_id(jf);
00500 jfp =
jf_journal_get_jfile(journal, file_id);
00501 open_mode =
jf_journal_file_get_open_mode(jfp);
00502
00503
00504
if (open_mode &
JF_FILE_OM_APPEND &&
00505 !(open_mode &
JF_FILE_OM_READ))
00506
THROW(NOTHING_TO_DO);
00507
00508
switch (whence) {
00509
case SEEK_SET:
00510 tmp_off = offset;
00511
break;
00512
case SEEK_CUR:
00513 tmp_off =
jf_journal_file_get_last_uc_pos(jfp) +
00514 offset;
00515
break;
00516
case SEEK_END:
00517 tmp_off =
jf_journal_file_get_last_uc_size(jfp) +
00518 offset;
00519
break;
00520
default:
00521
THROW(INVALID_WHENCE_VALUE);
00522 }
00523
00524
00525
if (tmp_off < 0 ||
00526 tmp_off >
jf_journal_file_get_last_uc_size(jfp))
00527
THROW(INVALID_OFFSET);
00528
00529 ret_cod =
jf_journal_file_set_last_uc_pos(jfp, tmp_off);
00530
if (
JF_RC_OK != ret_cod)
00531
THROW(SET_LAST_UC_POS);
00532
00533
THROW(NONE);
00534 }
CATCH {
00535
switch (excp) {
00536
case OBJ_NOT_SAFE:
00537 ret_cod =
JF_RC_OBJ_CORRUPTED;
00538
break;
00539
case INVALID_WHENCE_VALUE:
00540 ret_cod =
JF_RC_OUT_OF_RANGE;
00541
break;
00542
case INVALID_OFFSET:
00543 ret_cod =
JF_RC_INVALID_STREAM_POSITION;
00544
break;
00545
case SET_LAST_UC_POS:
00546
break;
00547
case NOTHING_TO_DO:
00548
case NONE:
00549 ret_cod =
JF_RC_OK;
00550
break;
00551
default:
00552 ret_cod =
JF_RC_INTERNAL_ERROR;
00553 }
00554 }
00555
JF_TRACE((
"jf_file_seek/excp=%d/ret_cod=%d/errno=%d\n",
00556 excp, ret_cod, errno));
00557
return ret_cod;
00558 }
00559
00560
00561
00562 int jf_file_size(
jf_file_t *jf,
jf_offset_t *last_size,
00563
jf_offset_t *last_uc_size)
00564 {
00565
enum Exception { OBJ_NOT_SAFE
00566 , NONE } excp;
00567
int ret_cod =
JF_RC_INTERNAL_ERROR;
00568
00569
JF_TRACE((
"jf_file_size\n"));
00570 TRY {
00571
jf_journal_t *journal;
00572
jf_word_t file_id;
00573
jf_journal_file_t *jfp;
00574
00575
if (!
jf_file_is_safe(jf))
00576
THROW(OBJ_NOT_SAFE);
00577
00578 journal =
jf_file_get_journal(jf);
00579 file_id =
jf_file_get_id(jf);
00580 jfp =
jf_journal_get_jfile(journal, file_id);
00581
00582
if (NULL != last_size)
00583 *last_size =
jf_journal_file_get_last_size(jfp);
00584
if (NULL != last_uc_size)
00585 *last_uc_size =
jf_journal_file_get_last_uc_size(jfp);
00586
00587
THROW(NONE);
00588 }
CATCH {
00589
switch (excp) {
00590
case OBJ_NOT_SAFE:
00591 ret_cod =
JF_RC_OBJ_CORRUPTED;
00592
break;
00593
case NONE:
00594 ret_cod =
JF_RC_OK;
00595
break;
00596
default:
00597 ret_cod =
JF_RC_INTERNAL_ERROR;
00598 }
00599 }
00600
JF_TRACE((
"jf_file_size/excp=%d/ret_cod=%d/errno=%d\n",
00601 excp, ret_cod, errno));
00602
return ret_cod;
00603 }
00604
00605
00606
00607 int jf_file_write(
jf_file_t *jf,
const void *data,
00608 size_t size, size_t *write_number)
00609 {
00610
enum Exception { NOTHING_TO_DO
00611 , JOURNAL_ADD_DATA
00612 , NONE } excp;
00613
int ret_cod =
JF_RC_INTERNAL_ERROR;
00614
00615
JF_TRACE((
"jf_file_write\n"));
00616 TRY {
00617
jf_journal_t *journal =
jf_file_get_journal(jf);
00618
00619
if (size == 0)
00620
THROW(NOTHING_TO_DO);
00621
00622 ret_cod =
jf_journal_add_byte_data(journal,
jf_file_get_id(jf),
00623 (
byte_t *)data, size);
00624
if (
JF_RC_OK != ret_cod)
00625
THROW(JOURNAL_ADD_DATA);
00626
00627 *write_number = size;
00628
THROW(NONE);
00629 }
CATCH {
00630
switch (excp) {
00631
case JOURNAL_ADD_DATA:
00632
break;
00633
case NOTHING_TO_DO:
00634
case NONE:
00635 ret_cod =
JF_RC_OK;
00636
break;
00637
default:
00638 ret_cod =
JF_RC_INTERNAL_ERROR;
00639 }
00640 }
00641
JF_TRACE((
"jf_file_write/excp=%d/ret_cod=%d/errno=%d\n",
00642 excp, ret_cod, errno));
00643
return ret_cod;
00644 }
00645
00646
00647
00648 int jf_file_read(
jf_file_t *jf,
void *data, size_t size, size_t *read_number)
00649 {
00650
enum Exception { JOURNAL_GET_DATA
00651 , NONE } excp;
00652
int ret_cod =
JF_RC_INTERNAL_ERROR;
00653
00654
JF_TRACE((
"jf_file_read\n"));
00655 TRY {
00656
jf_journal_t *journal =
jf_file_get_journal(jf);
00657
00658 ret_cod =
jf_journal_get_byte_data(
00659 journal,
jf_file_get_id(jf),
00660 (
byte_t *)data, size, read_number);
00661
if (
JF_RC_OK != ret_cod)
00662
THROW(JOURNAL_GET_DATA);
00663
00664
THROW(NONE);
00665 }
CATCH {
00666
switch (excp) {
00667
case JOURNAL_GET_DATA:
00668
break;
00669
case NONE:
00670 ret_cod =
JF_RC_OK;
00671
break;
00672
default:
00673 ret_cod =
JF_RC_INTERNAL_ERROR;
00674 }
00675 }
00676
JF_TRACE((
"jf_file_read/excp=%d/ret_cod=%d/errno=%d\n",
00677 excp, ret_cod, errno));
00678
return ret_cod;
00679 }
00680
00681
00682
00683 int jf_file_putc(
jf_file_t *jf,
int c)
00684 {
00685
enum Exception { JOURNAL_BUFFER_ADD_C
00686 , NONE } excp;
00687
int ret_cod =
JF_RC_INTERNAL_ERROR;
00688
00689
JF_TRACE((
"jf_file_putc\n"));
00690 TRY {
00691
jf_journal_t *journal =
jf_file_get_journal(jf);
00692
00693 ret_cod =
jf_journal_add_c(journal,
jf_file_get_id(jf), c);
00694
if (
JF_RC_OK != ret_cod)
00695
THROW(JOURNAL_BUFFER_ADD_C);
00696
00697
THROW(NONE);
00698 }
CATCH {
00699
switch (excp) {
00700
case JOURNAL_BUFFER_ADD_C:
00701
break;
00702
case NONE:
00703 ret_cod =
JF_RC_OK;
00704
break;
00705
default:
00706 ret_cod =
JF_RC_INTERNAL_ERROR;
00707 }
00708 }
00709
JF_TRACE((
"jf_file_putc/excp=%d/ret_cod=%d\n",
00710 excp, ret_cod));
00711
return ret_cod;
00712 }
00713
00714
00715
00716 int jf_file_puts(
jf_file_t *jf,
const char *s)
00717 {
00718
enum Exception { NOTHING_TO_DO
00719 , JOURNAL_ADD_DATA
00720 , NONE } excp;
00721
int ret_cod =
JF_RC_INTERNAL_ERROR;
00722
00723
JF_TRACE((
"jf_file_puts\n"));
00724 TRY {
00725
jf_journal_t *journal =
jf_file_get_journal(jf);
00726 size_t size = strlen(s);
00727
00728
if (size == 0)
00729
THROW(NOTHING_TO_DO);
00730
00731 ret_cod =
jf_journal_add_byte_data(journal,
jf_file_get_id(jf),
00732 (
byte_t *)s, size);
00733
if (
JF_RC_OK != ret_cod)
00734
THROW(JOURNAL_ADD_DATA);
00735
00736
THROW(NONE);
00737 }
CATCH {
00738
switch (excp) {
00739
case JOURNAL_ADD_DATA:
00740
break;
00741
case NOTHING_TO_DO:
00742
case NONE:
00743 ret_cod =
JF_RC_OK;
00744
break;
00745
default:
00746 ret_cod =
JF_RC_INTERNAL_ERROR;
00747 }
00748 }
00749
JF_TRACE((
"jf_file_puts/excp=%d/ret_cod=%d/errno=%d\n",
00750 excp, ret_cod, errno));
00751
return ret_cod;
00752 }
00753
00754
00755
00756 int jf_file_getc(
jf_file_t *jf,
int *c)
00757 {
00758
enum Exception { INVALID_OBJECT
00759 , JOURNAL_BUFFER_GET_C
00760 , NONE } excp;
00761
int ret_cod =
JF_RC_INTERNAL_ERROR;
00762
00763
JF_TRACE((
"jf_file_getc\n"));
00764 TRY {
00765
jf_journal_t *journal;
00766
jf_word_t jf_id;
00767
jf_journal_file_t *jfile;
00768
00769
if (!
jf_file_is_safe(jf))
00770
THROW(INVALID_OBJECT);
00771
00772 jf_id =
jf_file_get_id(jf);
00773 journal =
jf_file_get_journal(jf);
00774 jfile =
jf_journal_get_jfile(journal, jf_id);
00775
00776 ret_cod =
jf_journal_get_c(journal, jf_id, c);
00777
if (
JF_RC_OK != ret_cod)
00778
THROW(JOURNAL_BUFFER_GET_C);
00779 *c &= 0xff;
00780
00781
THROW(NONE);
00782 }
CATCH {
00783
switch (excp) {
00784
case INVALID_OBJECT:
00785 ret_cod =
JF_RC_OBJ_CORRUPTED;
00786
break;
00787
case JOURNAL_BUFFER_GET_C:
00788
break;
00789
case NONE:
00790 ret_cod =
JF_RC_OK;
00791
break;
00792
default:
00793 ret_cod =
JF_RC_INTERNAL_ERROR;
00794 }
00795 }
00796
JF_TRACE((
"jf_file_getc/excp=%d/ret_cod=%d/errno=%d\n",
00797 excp, ret_cod, errno));
00798
return ret_cod;
00799 }
00800
00801
00802
00803 int jf_file_gets(
jf_file_t *jf, size_t size,
char *s)
00804 {
00805
enum Exception { INVALID_OBJECT
00806 , JOURNAL_BUFFER_GET_C
00807 , NONE } excp;
00808
int ret_cod =
JF_RC_INTERNAL_ERROR;
00809
00810
JF_TRACE((
"jf_file_gets\n"));
00811 TRY {
00812 size_t i = 0;
00813
jf_journal_t *journal;
00814
jf_word_t jf_id;
00815
jf_journal_file_t *jfile;
00816
00817
if (!
jf_file_is_safe(jf))
00818
THROW(INVALID_OBJECT);
00819
00820 jf_id =
jf_file_get_id(jf);
00821 journal =
jf_file_get_journal(jf);
00822 jfile =
jf_journal_get_jfile(journal, jf_id);
00823
00824
for (i = 0; i < size - 1; ++i) {
00825
int c;
00826 ret_cod =
jf_journal_get_c(
00827 journal,
jf_file_get_id(jf), &c);
00828
if (
JF_RC_EOF == ret_cod)
00829
break;
00830
if (
JF_RC_OK != ret_cod)
00831
THROW(JOURNAL_BUFFER_GET_C);
00832 c &= 0xff;
00833 s[i] = c;
00834
if (c ==
'\n')
00835
break;
00836 }
00837 s[++i] =
'\0';
00838
00839
THROW(NONE);
00840 }
CATCH {
00841
switch (excp) {
00842
case INVALID_OBJECT:
00843 ret_cod =
JF_RC_OBJ_CORRUPTED;
00844
break;
00845
case JOURNAL_BUFFER_GET_C:
00846
break;
00847
case NONE:
00848 ret_cod =
JF_RC_OK;
00849
break;
00850
default:
00851 ret_cod =
JF_RC_INTERNAL_ERROR;
00852 }
00853 }
00854
JF_TRACE((
"jf_file_gets/excp=%d/"
00855
"ret_cod=%d/errno=%d\n", excp, ret_cod, errno));
00856
return ret_cod;
00857 }
00858
00859
00860
00861
#ifdef HAVE_VSNPRINTF
00862 int jf_file_printf(
jf_file_t *jf, size_t *write_number,
00863
const char *format, ...)
00864 {
00865
enum Exception { VPRINTF_ERROR
00866 , NONE } excp;
00867
int ret_cod =
JF_RC_INTERNAL_ERROR;
00868
00869
JF_TRACE((
"jf_file_printf\n"));
00870 TRY {
00871 va_list ap;
00872 va_start(ap, format);
00873
00874 ret_cod =
jf_file_vprintf(jf, write_number, format, ap);
00875
if (
JF_RC_OK != ret_cod)
00876
THROW(VPRINTF_ERROR);
00877
00878 va_end(ap);
00879
00880
THROW(NONE);
00881 }
CATCH {
00882
switch (excp) {
00883
case VPRINTF_ERROR:
00884
break;
00885
case NONE:
00886 ret_cod =
JF_RC_OK;
00887
break;
00888
default:
00889 ret_cod =
JF_RC_INTERNAL_ERROR;
00890 }
00891 }
00892
JF_TRACE((
"jf_file_printf/excp=%d/"
00893
"ret_cod=%d/errno=%d\n", excp, ret_cod, errno));
00894
return ret_cod;
00895 }
00896
00897
00898
00899 int jf_file_vprintf(
jf_file_t *jf, size_t *write_number,
const char *format,
00900 va_list ap)
00901 {
00902
enum Exception { INVALID_BUFFER
00903 , MALLOC_ERROR1
00904 , VSNPRINTF_ERROR
00905 , MALLOC_ERROR2
00906 , FILE_WRITE
00907 , NONE } excp;
00908
int ret_cod =
JF_RC_INTERNAL_ERROR;
00909
00910
JF_TRACE((
"jf_file_vprintf\n"));
00911 TRY {
00912
int chars;
00913 *write_number = 0;
00914 uint32_t flags;
00915
00916
# ifdef _EXTRA_CHECK
00917
if ((NULL == jf->
char_buffer && 0 != jf->
char_buffer_size) ||
00918 (NULL != jf->
char_buffer && 0 == jf->
char_buffer_size))
00919
THROW(INVALID_BUFFER);
00920
# endif
00921
00922
if (NULL == jf->
char_buffer) {
00923 jf->
char_buffer = (
char *)malloc(
00924
JF_FILE_BUFFER_PAGE_SIZE);
00925
if (NULL == jf->
char_buffer)
00926
THROW(MALLOC_ERROR1);
00927 jf->
char_buffer_size =
JF_FILE_BUFFER_PAGE_SIZE;
00928 }
00929
00930
while (
TRUE) {
00931 va_list aq;
00932
# ifdef HAVE_VA_COPY
00933
va_copy(aq, ap);
00934
# else
00935
if (
sizeof(aq) ==
sizeof(ap))
00936 memcpy(&aq, &ap,
sizeof(va_list));
00937
else
00938 memcpy(&aq, ap,
sizeof(va_list));
00939
# endif
00940 chars = vsnprintf(jf->
char_buffer,
00941 jf->
char_buffer_size, format, aq);
00942 va_end(aq);
00943
00944
if (chars > 0 && chars < jf->
char_buffer_size)
00945
break;
00946
00947
if (chars < 0)
00948
THROW(VSNPRINTF_ERROR);
00949 free(jf->
char_buffer);
00950 jf->
char_buffer_size +=
JF_FILE_BUFFER_PAGE_SIZE;
00951 jf->
char_buffer = (
char *)malloc(jf->
char_buffer_size);
00952
if (NULL == jf->
char_buffer)
00953
THROW(MALLOC_ERROR2);
00954 }
00955
00956 ret_cod =
jf_file_write(jf, jf->
char_buffer, chars,
00957 write_number);
00958
if (
JF_RC_OK != ret_cod)
00959
THROW(FILE_WRITE);
00960
00961 flags =
jf_journal_get_open_opts_flags(
00962
jf_file_get_journal(jf));
00963
if ((flags &
JF_JOURNAL_PROP_VIRTMEM_LOW) ||
00964 ((flags &
JF_JOURNAL_PROP_VIRTMEM_MEDIUM) &&
00965 (chars +
JF_FILE_BUFFER_PAGE_SIZE <
00966 jf->
char_buffer_size))) {
00967
00968 free(jf->
char_buffer);
00969 jf->
char_buffer = NULL;
00970 jf->
char_buffer_size = 0;
00971 }
00972
00973
THROW(NONE);
00974 }
CATCH {
00975
switch (excp) {
00976
case INVALID_BUFFER:
00977 ret_cod =
JF_RC_INVALID_STATUS;
00978
break;
00979
case MALLOC_ERROR1:
00980
case MALLOC_ERROR2:
00981 ret_cod =
JF_RC_MALLOC_ERROR;
00982
break;
00983
case VSNPRINTF_ERROR:
00984 ret_cod =
JF_RC_VSNPRINTF_ERROR;
00985
break;
00986
case FILE_WRITE:
00987
break;
00988
case NONE:
00989 ret_cod =
JF_RC_OK;
00990
break;
00991
default:
00992 ret_cod =
JF_RC_INTERNAL_ERROR;
00993 }
00994 }
00995
JF_TRACE((
"jf_file_vprintf/excp=%d/"
00996
"ret_cod=%d/errno=%d\n", excp, ret_cod, errno));
00997
return ret_cod;
00998 }
00999
#endif
01000
01001
01002