Mercurial > libpst
comparison src/libpst.c @ 230:42b38d65f7e4
patches from Justin Greer
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Thu, 10 Sep 2009 13:01:08 -0700 |
parents | fef2214083a4 |
children | fe64279df92b |
comparison
equal
deleted
inserted
replaced
229:e7f363452178 | 230:42b38d65f7e4 |
---|---|
63 | 63 |
64 | 64 |
65 typedef struct pst_holder { | 65 typedef struct pst_holder { |
66 char **buf; | 66 char **buf; |
67 FILE *fp; | 67 FILE *fp; |
68 int base64; | 68 int base64; // bool, are we encoding into base64 |
69 int base64_line_count; // base64 bytes emitted on the current line | |
70 size_t base64_extra; // count of bytes held in base64_extra_chars | |
71 char base64_extra_chars[2]; // up to two pending unencoded bytes | |
69 } pst_holder; | 72 } pst_holder; |
70 | 73 |
71 | 74 |
72 typedef struct pst_subblock { | 75 typedef struct pst_subblock { |
73 char *buf; | 76 char *buf; |
250 0x27, 0x3b, 0xda, 0xba, 0xd7, 0xc2, 0x26, 0xd4, 0x91, 0x1d, 0xd2, 0x1c, 0x22, 0x33, 0xf8, 0xfa, | 253 0x27, 0x3b, 0xda, 0xba, 0xd7, 0xc2, 0x26, 0xd4, 0x91, 0x1d, 0xd2, 0x1c, 0x22, 0x33, 0xf8, 0xfa, |
251 0xf1, 0x5a, 0xef, 0xcf, 0x90, 0xb6, 0x8b, 0xb5, 0xbd, 0xc0, 0xbf, 0x08, 0x97, 0x1e, 0x6c, 0xe2, | 254 0xf1, 0x5a, 0xef, 0xcf, 0x90, 0xb6, 0x8b, 0xb5, 0xbd, 0xc0, 0xbf, 0x08, 0x97, 0x1e, 0x6c, 0xe2, |
252 0x61, 0xe0, 0xc6, 0xc1, 0x59, 0xab, 0xbb, 0x58, 0xde, 0x5f, 0xdf, 0x60, 0x79, 0x7e, 0xb2, 0x8a | 255 0x61, 0xe0, 0xc6, 0xc1, 0x59, 0xab, 0xbb, 0x58, 0xde, 0x5f, 0xdf, 0x60, 0x79, 0x7e, 0xb2, 0x8a |
253 }; | 256 }; |
254 | 257 |
258 static size_t pst_append_holder(pst_holder *h, size_t size, char **buf, size_t z); | |
255 static int pst_build_desc_ptr(pst_file *pf, int64_t offset, int32_t depth, uint64_t linku1, uint64_t start_val, uint64_t end_val); | 259 static int pst_build_desc_ptr(pst_file *pf, int64_t offset, int32_t depth, uint64_t linku1, uint64_t start_val, uint64_t end_val); |
256 static pst_id2_tree* pst_build_id2(pst_file *pf, pst_index_ll* list); | 260 static pst_id2_tree* pst_build_id2(pst_file *pf, pst_index_ll* list); |
257 static int pst_build_id_ptr(pst_file *pf, int64_t offset, int32_t depth, uint64_t linku1, uint64_t start_val, uint64_t end_val); | 261 static int pst_build_id_ptr(pst_file *pf, int64_t offset, int32_t depth, uint64_t linku1, uint64_t start_val, uint64_t end_val); |
258 static int pst_chr_count(char *str, char x); | 262 static int pst_chr_count(char *str, char x); |
259 static size_t pst_ff_compile_ID(pst_file *pf, uint64_t i_id, pst_holder *h, size_t size); | 263 static size_t pst_ff_compile_ID(pst_file *pf, uint64_t i_id, pst_holder *h, size_t size); |
260 static size_t pst_ff_getIDblock(pst_file *pf, uint64_t i_id, char** buf); | 264 static size_t pst_ff_getIDblock(pst_file *pf, uint64_t i_id, char** buf); |
261 static size_t pst_ff_getID2block(pst_file *pf, uint64_t id2, pst_id2_tree *id2_head, char** buf); | 265 static size_t pst_ff_getID2block(pst_file *pf, uint64_t id2, pst_id2_tree *id2_head, char** buf); |
262 static size_t pst_ff_getID2data(pst_file *pf, pst_index_ll *ptr, pst_holder *h); | 266 static size_t pst_ff_getID2data(pst_file *pf, pst_index_ll *ptr, pst_holder *h); |
267 static size_t pst_finish_cleanup_holder(pst_holder *h, size_t size); | |
263 static void pst_free_attach(pst_item_attach *attach); | 268 static void pst_free_attach(pst_item_attach *attach); |
264 static void pst_free_desc (pst_desc_tree *head); | 269 static void pst_free_desc (pst_desc_tree *head); |
265 static void pst_free_id2(pst_id2_tree * head); | 270 static void pst_free_id2(pst_id2_tree * head); |
266 static void pst_free_id (pst_index_ll *head); | 271 static void pst_free_id (pst_index_ll *head); |
267 static void pst_free_list(pst_mapi_object *list); | 272 static void pst_free_list(pst_mapi_object *list); |
535 | 540 |
536 | 541 |
537 pst_binary pst_attach_to_mem(pst_file *pf, pst_item_attach *attach) { | 542 pst_binary pst_attach_to_mem(pst_file *pf, pst_item_attach *attach) { |
538 pst_index_ll *ptr; | 543 pst_index_ll *ptr; |
539 pst_binary rc; | 544 pst_binary rc; |
540 pst_holder h = {&rc.data, NULL, 0}; | 545 pst_holder h = {&rc.data, NULL, 0, 0, 0}; |
541 rc.size = 0; | 546 rc.size = 0; |
542 rc.data = NULL; | 547 rc.data = NULL; |
543 DEBUG_ENT("pst_attach_to_mem"); | 548 DEBUG_ENT("pst_attach_to_mem"); |
544 if ((!attach->data.data) && (attach->i_id != (uint64_t)-1)) { | 549 if ((!attach->data.data) && (attach->i_id != (uint64_t)-1)) { |
545 ptr = pst_getID(pf, attach->i_id); | 550 ptr = pst_getID(pf, attach->i_id); |
558 } | 563 } |
559 | 564 |
560 | 565 |
561 size_t pst_attach_to_file(pst_file *pf, pst_item_attach *attach, FILE* fp) { | 566 size_t pst_attach_to_file(pst_file *pf, pst_item_attach *attach, FILE* fp) { |
562 pst_index_ll *ptr; | 567 pst_index_ll *ptr; |
563 pst_holder h = {NULL, fp, 0}; | 568 pst_holder h = {NULL, fp, 0, 0, 0}; |
564 size_t size = 0; | 569 size_t size = 0; |
565 DEBUG_ENT("pst_attach_to_file"); | 570 DEBUG_ENT("pst_attach_to_file"); |
566 if ((!attach->data.data) && (attach->i_id != (uint64_t)-1)) { | 571 if ((!attach->data.data) && (attach->i_id != (uint64_t)-1)) { |
567 ptr = pst_getID(pf, attach->i_id); | 572 ptr = pst_getID(pf, attach->i_id); |
568 if (ptr) { | 573 if (ptr) { |
582 } | 587 } |
583 | 588 |
584 | 589 |
585 size_t pst_attach_to_file_base64(pst_file *pf, pst_item_attach *attach, FILE* fp) { | 590 size_t pst_attach_to_file_base64(pst_file *pf, pst_item_attach *attach, FILE* fp) { |
586 pst_index_ll *ptr; | 591 pst_index_ll *ptr; |
587 pst_holder h = {NULL, fp, 1}; | 592 pst_holder h = {NULL, fp, 1, 0, 0}; |
588 size_t size = 0; | 593 size_t size = 0; |
589 DEBUG_ENT("pst_attach_to_file_base64"); | 594 DEBUG_ENT("pst_attach_to_file_base64"); |
590 if ((!attach->data.data) && (attach->i_id != (uint64_t)-1)) { | 595 if ((!attach->data.data) && (attach->i_id != (uint64_t)-1)) { |
591 ptr = pst_getID(pf, attach->i_id); | 596 ptr = pst_getID(pf, attach->i_id); |
592 if (ptr) { | 597 if (ptr) { |
939 | 944 |
940 | 945 |
941 static size_t pst_decode_type3(pst_file *pf, pst_table3_rec *table3_rec, char *buf); | 946 static size_t pst_decode_type3(pst_file *pf, pst_table3_rec *table3_rec, char *buf); |
942 static size_t pst_decode_type3(pst_file *pf, pst_table3_rec *table3_rec, char *buf) { | 947 static size_t pst_decode_type3(pst_file *pf, pst_table3_rec *table3_rec, char *buf) { |
943 size_t r; | 948 size_t r; |
949 DEBUG_ENT("pst_decode_type3"); | |
944 if (pf->do_read64) { | 950 if (pf->do_read64) { |
945 DEBUG_INFO(("Decoding table3 64\n")); | 951 DEBUG_INFO(("Decoding table3 64\n")); |
946 DEBUG_HEXDUMPC(buf, sizeof(pst_table3_rec), 0x10); | 952 DEBUG_HEXDUMPC(buf, sizeof(pst_table3_rec), 0x10); |
947 memcpy(table3_rec, buf, sizeof(pst_table3_rec)); | 953 memcpy(table3_rec, buf, sizeof(pst_table3_rec)); |
948 LE64_CPU(table3_rec->id); | 954 LE64_CPU(table3_rec->id); |
954 memcpy(&table3_rec32, buf, sizeof(pst_table3_rec32)); | 960 memcpy(&table3_rec32, buf, sizeof(pst_table3_rec32)); |
955 LE32_CPU(table3_rec32.id); | 961 LE32_CPU(table3_rec32.id); |
956 table3_rec->id = table3_rec32.id; | 962 table3_rec->id = table3_rec32.id; |
957 r = sizeof(pst_table3_rec32); | 963 r = sizeof(pst_table3_rec32); |
958 } | 964 } |
965 DEBUG_RET(); | |
959 return r; | 966 return r; |
960 } | 967 } |
961 | 968 |
962 | 969 |
963 /** Process the index1 b-tree from the pst file and create the | 970 /** Process the index1 b-tree from the pst file and create the |
3909 | 3916 |
3910 | 3917 |
3911 static size_t pst_ff_getID2block(pst_file *pf, uint64_t id2, pst_id2_tree *id2_head, char** buf) { | 3918 static size_t pst_ff_getID2block(pst_file *pf, uint64_t id2, pst_id2_tree *id2_head, char** buf) { |
3912 size_t ret; | 3919 size_t ret; |
3913 pst_id2_tree* ptr; | 3920 pst_id2_tree* ptr; |
3914 pst_holder h = {buf, NULL, 0}; | 3921 pst_holder h = {buf, NULL, 0, 0, 0}; |
3915 DEBUG_ENT("pst_ff_getID2block"); | 3922 DEBUG_ENT("pst_ff_getID2block"); |
3916 ptr = pst_getID2(id2_head, id2); | 3923 ptr = pst_getID2(id2_head, id2); |
3917 | 3924 |
3918 if (!ptr) { | 3925 if (!ptr) { |
3919 DEBUG_WARN(("Cannot find id2 value %#"PRIi64"\n", id2)); | 3926 DEBUG_WARN(("Cannot find id2 value %#"PRIi64"\n", id2)); |
3924 DEBUG_RET(); | 3931 DEBUG_RET(); |
3925 return ret; | 3932 return ret; |
3926 } | 3933 } |
3927 | 3934 |
3928 | 3935 |
3936 /** find the actual data from an i_id and send it to the destination | |
3937 * specified by the pst_holder h. h must be a new empty destination. | |
3938 * | |
3939 * @param pf PST file structure | |
3940 * @param ptr | |
3941 * @param h specifies the output destination (buffer, file, encoding) | |
3942 * @return updated size of the output | |
3943 */ | |
3929 static size_t pst_ff_getID2data(pst_file *pf, pst_index_ll *ptr, pst_holder *h) { | 3944 static size_t pst_ff_getID2data(pst_file *pf, pst_index_ll *ptr, pst_holder *h) { |
3930 size_t ret; | 3945 size_t ret; |
3931 char *b = NULL, *t; | 3946 char *b = NULL; |
3932 DEBUG_ENT("pst_ff_getID2data"); | 3947 DEBUG_ENT("pst_ff_getID2data"); |
3933 if (!(ptr->i_id & 0x02)) { | 3948 if (!(ptr->i_id & 0x02)) { |
3934 ret = pst_ff_getIDblock_dec(pf, ptr->i_id, &b); | 3949 ret = pst_ff_getIDblock_dec(pf, ptr->i_id, &b); |
3935 if (h->buf) { | 3950 ret = pst_append_holder(h, (size_t)0, &b, ret); |
3936 *(h->buf) = b; | 3951 free(b); |
3937 } else if ((h->base64 == 1) && h->fp) { | |
3938 t = pst_base64_encode(b, ret); | |
3939 if (t) { | |
3940 (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); | |
3941 free(t); // caught by valgrind | |
3942 } | |
3943 free(b); | |
3944 } else if (h->fp) { | |
3945 (void)pst_fwrite(b, (size_t)1, ret, h->fp); | |
3946 free(b); | |
3947 } else { | |
3948 // h-> does not specify any output | |
3949 } | |
3950 | |
3951 } else { | 3952 } else { |
3952 // here we will assume it is a block that points to others | 3953 // here we will assume it is an indirection block that points to others |
3953 DEBUG_INFO(("Assuming it is a multi-block record because of it's id\n")); | 3954 DEBUG_INFO(("Assuming it is a multi-block record because of it's id\n")); |
3954 ret = pst_ff_compile_ID(pf, ptr->i_id, h, (size_t)0); | 3955 ret = pst_ff_compile_ID(pf, ptr->i_id, h, (size_t)0); |
3955 } | 3956 } |
3957 ret = pst_finish_cleanup_holder(h, ret); | |
3956 DEBUG_RET(); | 3958 DEBUG_RET(); |
3957 return ret; | 3959 return ret; |
3958 } | 3960 } |
3959 | 3961 |
3960 | 3962 |
3963 /** find the actual data from an indirection i_id and send it to the destination | |
3964 * specified by the pst_holder. | |
3965 * | |
3966 * @param pf PST file structure | |
3967 * @param i_id ID of the block to read | |
3968 * @param h specifies the output destination (buffer, file, encoding) | |
3969 * @param size number of bytes of data already sent to h | |
3970 * @return updated size of the output | |
3971 */ | |
3961 static size_t pst_ff_compile_ID(pst_file *pf, uint64_t i_id, pst_holder *h, size_t size) { | 3972 static size_t pst_ff_compile_ID(pst_file *pf, uint64_t i_id, pst_holder *h, size_t size) { |
3962 size_t z, a; | 3973 size_t z, a; |
3963 uint16_t count, y; | 3974 uint16_t count, y; |
3964 char *buf3 = NULL, *buf2 = NULL, *t; | 3975 char *buf3 = NULL; |
3965 char *b_ptr; | 3976 char *buf2 = NULL; |
3966 int line_count = 0; | 3977 char *b_ptr; |
3967 char base64_extra_chars[3]; | 3978 int line_count = 0; |
3968 uint32_t base64_extra = 0; | |
3969 pst_block_hdr block_hdr; | 3979 pst_block_hdr block_hdr; |
3970 pst_table3_rec table3_rec; //for type 3 (0x0101) blocks | 3980 pst_table3_rec table3_rec; //for type 3 (0x0101) blocks |
3971 | 3981 |
3972 DEBUG_ENT("pst_ff_compile_ID"); | 3982 DEBUG_ENT("pst_ff_compile_ID"); |
3973 a = pst_ff_getIDblock(pf, i_id, &buf3); | 3983 a = pst_ff_getIDblock(pf, i_id, &buf3); |
3981 LE16_CPU(block_hdr.index_offset); | 3991 LE16_CPU(block_hdr.index_offset); |
3982 LE16_CPU(block_hdr.type); | 3992 LE16_CPU(block_hdr.type); |
3983 LE32_CPU(block_hdr.offset); | 3993 LE32_CPU(block_hdr.offset); |
3984 DEBUG_INFO(("block header (index_offset=%#hx, type=%#hx, offset=%#x)\n", block_hdr.index_offset, block_hdr.type, block_hdr.offset)); | 3994 DEBUG_INFO(("block header (index_offset=%#hx, type=%#hx, offset=%#x)\n", block_hdr.index_offset, block_hdr.type, block_hdr.offset)); |
3985 | 3995 |
3996 count = block_hdr.type; | |
3997 b_ptr = buf3 + 8; | |
3998 | |
3999 // For indirect lookups through a table of i_ids, just recurse back into this | |
4000 // function, letting it concatenate all the data together, and then return the | |
4001 // total size of the data. | |
4002 if (block_hdr.index_offset == (uint16_t)0x0201) { // Indirect lookup (depth 2). | |
4003 for (y=0; y<count; y++) { | |
4004 b_ptr += pst_decode_type3(pf, &table3_rec, b_ptr); | |
4005 size = pst_ff_compile_ID(pf, table3_rec.id, h, size); | |
4006 } | |
4007 free(buf3); | |
4008 DEBUG_RET(); | |
4009 return size; | |
4010 } | |
4011 | |
3986 if (block_hdr.index_offset != (uint16_t)0x0101) { //type 3 | 4012 if (block_hdr.index_offset != (uint16_t)0x0101) { //type 3 |
3987 DEBUG_WARN(("WARNING: not a type 0x0101 buffer, Treating as normal buffer\n")); | 4013 DEBUG_WARN(("WARNING: not a type 0x0101 buffer, Treating as normal buffer\n")); |
3988 if (pf->encryption) (void)pst_decrypt(i_id, buf3, a, pf->encryption); | 4014 if (pf->encryption) (void)pst_decrypt(i_id, buf3, a, pf->encryption); |
3989 if (h->buf) | 4015 size = pst_append_holder(h, size, &buf3, a); |
3990 *(h->buf) = buf3; | 4016 free(buf3); |
3991 else if (h->base64 == 1 && h->fp) { | |
3992 t = pst_base64_encode(buf3, a); | |
3993 if (t) { | |
3994 (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); | |
3995 free(t); // caught by valgrind | |
3996 } | |
3997 free(buf3); | |
3998 } else if (h->fp) { | |
3999 (void)pst_fwrite(buf3, (size_t)1, a, h->fp); | |
4000 free(buf3); | |
4001 } else { | |
4002 // h-> does not specify any output | |
4003 } | |
4004 DEBUG_RET(); | 4017 DEBUG_RET(); |
4005 return a; | 4018 return size; |
4006 } | 4019 } |
4007 count = block_hdr.type; | 4020 |
4008 b_ptr = buf3 + 8; | |
4009 line_count = 0; | |
4010 for (y=0; y<count; y++) { | 4021 for (y=0; y<count; y++) { |
4011 b_ptr += pst_decode_type3(pf, &table3_rec, b_ptr); | 4022 b_ptr += pst_decode_type3(pf, &table3_rec, b_ptr); |
4012 z = pst_ff_getIDblock_dec(pf, table3_rec.id, &buf2); | 4023 z = pst_ff_getIDblock_dec(pf, table3_rec.id, &buf2); |
4013 if (!z) { | 4024 if (!z) { |
4014 DEBUG_WARN(("call to getIDblock returned zero %i\n", z)); | 4025 DEBUG_WARN(("call to getIDblock returned zero %i\n", z)); |
4015 if (buf2) free(buf2); | 4026 if (buf2) free(buf2); |
4016 free(buf3); | 4027 free(buf3); |
4017 DEBUG_RET(); | 4028 DEBUG_RET(); |
4018 return z; | 4029 return z; |
4019 } | 4030 } |
4020 if (h->buf) { | 4031 size = pst_append_holder(h, size, &buf2, z); |
4021 *(h->buf) = realloc(*(h->buf), size+z+1); | 4032 } |
4022 DEBUG_INFO(("appending read data of size %i onto main buffer from pos %i\n", z, size)); | 4033 |
4023 memcpy(&((*(h->buf))[size]), buf2, z); | 4034 free(buf3); |
4024 } else if ((h->base64 == 1) && h->fp) { | 4035 if (buf2) free(buf2); |
4025 if (base64_extra) { | 4036 DEBUG_RET(); |
4026 // include any bytes left over from the last encoding | 4037 return size; |
4027 buf2 = (char*)realloc(buf2, z+base64_extra); | 4038 } |
4028 memmove(buf2+base64_extra, buf2, z); | 4039 |
4029 memcpy(buf2, base64_extra_chars, base64_extra); | 4040 |
4030 z += base64_extra; | 4041 /** append (buf,z) data to the output destination (h,size) |
4031 } | 4042 * |
4032 | 4043 * @param h specifies the output destination (buffer, file, encoding) |
4033 // find out how many bytes will be left over after this encoding and save them | 4044 * @param size number of bytes of data already sent to h |
4034 base64_extra = z % 3; | 4045 * @param buf reference to a pointer to the buffer to be appended to the destination |
4035 if (base64_extra) { | 4046 * @param z number of bytes in buf |
4036 z -= base64_extra; | 4047 * @return updated size of the output, buffer pointer possibly reallocated |
4037 memcpy(base64_extra_chars, buf2+z, base64_extra); | 4048 */ |
4038 } | 4049 static size_t pst_append_holder(pst_holder *h, size_t size, char **buf, size_t z) { |
4039 | 4050 char *t; |
4040 // encode this chunk | 4051 DEBUG_ENT("pst_append_holder"); |
4041 t = pst_base64_encode_multiple(buf2, z, &line_count); | 4052 |
4042 if (t) { | 4053 // raw append to a buffer |
4043 DEBUG_INFO(("writing %i bytes to file as base64 [%i]. Currently %i\n", z, strlen(t), size)); | 4054 if (h->buf) { |
4044 (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); | 4055 *(h->buf) = realloc(*(h->buf), size+z+1); |
4045 free(t); // caught by valgrind | 4056 DEBUG_INFO(("appending read data of size %i onto main buffer from pos %i\n", z, size)); |
4046 } | 4057 memcpy(*(h->buf)+size, *buf, z); |
4047 } else if (h->fp) { | 4058 |
4048 DEBUG_INFO(("writing %i bytes to file. Currently %i\n", z, size)); | 4059 // base64 encoding to a file |
4049 (void)pst_fwrite(buf2, (size_t)1, z, h->fp); | 4060 } else if ((h->base64 == 1) && h->fp) { |
4050 } else { | 4061 // |
4051 // h-> does not specify any output | 4062 if (h->base64_extra) { |
4052 } | 4063 // include any bytes left over from the last encoding |
4053 size += z; | 4064 *buf = (char*)realloc(*buf, z+h->base64_extra); |
4054 } | 4065 memmove(*buf+h->base64_extra, *buf, z); |
4055 if ((h->base64 == 1) && h->fp && base64_extra) { | 4066 memcpy(*buf, h->base64_extra_chars, h->base64_extra); |
4067 z += h->base64_extra; | |
4068 } | |
4069 | |
4070 // find out how many bytes will be left over after this encoding and save them | |
4071 h->base64_extra = z % 3; | |
4072 if (h->base64_extra) { | |
4073 z -= h->base64_extra; | |
4074 memcpy(h->base64_extra_chars, *buf+z, h->base64_extra); | |
4075 } | |
4076 | |
4077 // encode this chunk | |
4078 t = pst_base64_encode_multiple(*buf, z, &h->base64_line_count); | |
4079 if (t) { | |
4080 DEBUG_INFO(("writing %i bytes to file as base64 [%i]. Currently %i\n", z, strlen(t), size)); | |
4081 (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); | |
4082 free(t); // caught by valgrind | |
4083 } | |
4084 | |
4085 // raw append to a file | |
4086 } else if (h->fp) { | |
4087 DEBUG_INFO(("writing %i bytes to file. Currently %i\n", z, size)); | |
4088 (void)pst_fwrite(*buf, (size_t)1, z, h->fp); | |
4089 | |
4090 // null output | |
4091 } else { | |
4092 // h-> does not specify any output | |
4093 } | |
4094 DEBUG_RET(); | |
4095 return size+z; | |
4096 } | |
4097 | |
4098 | |
4099 /** finish cleanup for base64 encoding to a file with extra bytes left over | |
4100 * | |
4101 * @param h specifies the output destination (buffer, file, encoding) | |
4102 * @param size number of bytes of data already sent to h | |
4103 * @return updated size of the output | |
4104 */ | |
4105 static size_t pst_finish_cleanup_holder(pst_holder *h, size_t size) { | |
4106 char *t; | |
4107 DEBUG_ENT("pst_finish_cleanup_holder"); | |
4108 if ((h->base64 == 1) && h->fp && h->base64_extra) { | |
4056 // need to encode any bytes left over | 4109 // need to encode any bytes left over |
4057 t = pst_base64_encode_multiple(base64_extra_chars, (size_t)base64_extra, &line_count); | 4110 t = pst_base64_encode_multiple(h->base64_extra_chars, h->base64_extra, &h->base64_line_count); |
4058 if (t) { | 4111 if (t) { |
4059 (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); | 4112 (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); |
4060 free(t); // caught by valgrind | 4113 free(t); // caught by valgrind |
4061 } | 4114 } |
4062 } | 4115 size += h->base64_extra; |
4063 free(buf3); | 4116 } |
4064 if (buf2) free(buf2); | |
4065 DEBUG_RET(); | 4117 DEBUG_RET(); |
4066 return size; | 4118 return size; |
4067 } | 4119 } |
4068 | 4120 |
4069 | 4121 |
4244 static const char* codepage(int cp, int buflen, char* result) { | 4296 static const char* codepage(int cp, int buflen, char* result) { |
4245 switch (cp) { | 4297 switch (cp) { |
4246 case 932 : return "iso-2022-jp"; | 4298 case 932 : return "iso-2022-jp"; |
4247 case 936 : return "gb2313"; | 4299 case 936 : return "gb2313"; |
4248 case 950 : return "big5"; | 4300 case 950 : return "big5"; |
4301 case 1200 : return "ucs-2le"; | |
4302 case 1201 : return "ucs-2be"; | |
4249 case 20127 : return "us-ascii"; | 4303 case 20127 : return "us-ascii"; |
4250 case 20269 : return "iso-6937"; | 4304 case 20269 : return "iso-6937"; |
4251 case 20865 : return "iso-8859-15"; | 4305 case 20865 : return "iso-8859-15"; |
4252 case 20866 : return "koi8-r"; | 4306 case 20866 : return "koi8-r"; |
4253 case 21866 : return "koi8-u"; | 4307 case 21866 : return "koi8-u"; |