root/openpgpsdk/trunk/src/memory.c

Revision 371 (checked in by ben, 7 years ago)

Make sure dmalloc happens last.

Line 
1 /** \file
2  */
3
4 #include <openpgpsdk/create.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <assert.h>
8
9 #include <openpgpsdk/final.h>
10
11 struct ops_memory
12     {
13     unsigned char *buf;
14     size_t length;
15     size_t allocated;
16     };
17
18 void ops_memory_init(ops_memory_t *mem,size_t initial_size)
19     {
20     mem->length=0;
21     if(mem->buf)
22         {
23         if(mem->allocated < initial_size)
24             {
25             mem->buf=realloc(mem->buf,initial_size);
26             mem->allocated=initial_size;
27             }
28         return;
29         }
30     mem->buf=malloc(initial_size);
31     mem->allocated=initial_size;
32     }
33
34 void ops_memory_pad(ops_memory_t *mem,size_t length)
35     {
36     assert(mem->allocated >= mem->length);
37     if(mem->allocated < mem->length+length)
38         {
39         mem->allocated=mem->allocated*2+length;
40         mem->buf=realloc(mem->buf,mem->allocated);
41         }
42     assert(mem->allocated >= mem->length+length);
43     }
44
45 void ops_memory_add(ops_memory_t *mem,const unsigned char *src,size_t length)
46     {
47     ops_memory_pad(mem,length);
48     memcpy(mem->buf+mem->length,src,length);
49     mem->length+=length;
50     }
51
52 // XXX: this could be refactored via the writer, but an awful lot of
53 // hoops to jump through for 2 lines of code!
54 void ops_memory_place_int(ops_memory_t *mem,unsigned offset,unsigned n,
55                           size_t length)
56     {
57     assert(mem->allocated >= offset+length);
58    
59     while(length--)
60         mem->buf[offset++]=n >> (length*8);
61     }
62
63 /**
64  * Unlike ops_memory_release(), this retains the allocated memory but
65  * sets the length of stored data to zero.
66  */
67 void ops_memory_clear(ops_memory_t *mem)
68     { mem->length=0; }
69
70 void ops_memory_release(ops_memory_t *mem)
71     {
72     free(mem->buf);
73     mem->buf=NULL;
74     mem->length=0;
75     }
76
77 static ops_boolean_t memory_writer(const unsigned char *src,unsigned length,
78                                       ops_error_t **errors,
79                                       ops_writer_info_t *winfo)
80     {
81     ops_memory_t *mem=ops_writer_get_arg(winfo);
82
83     OPS_USED(errors);
84     ops_memory_add(mem,src,length);
85     return ops_true;
86     }
87
88 /**
89  * \ingroup Create
90  *
91  * Set a memory writer. Note that it is the caller's resposibility to
92  * release mem.
93  *
94  * \param info The info structure
95  * \param mem The memory structure */
96
97 void ops_writer_set_memory(ops_create_info_t *info,ops_memory_t *mem)
98     {
99     ops_writer_set(info,memory_writer,NULL,NULL,mem);
100     }
101
102 void ops_memory_make_packet(ops_memory_t *out,ops_content_tag_t tag)
103     {
104     size_t extra;
105
106     if(out->length < 192)
107         extra=1;
108     else if(out->length < 8384)
109         extra=2;
110     else
111         extra=5;
112
113     ops_memory_pad(out,extra+1);
114     memmove(out->buf+extra+1,out->buf,out->length);
115
116     out->buf[0]=OPS_PTAG_ALWAYS_SET|OPS_PTAG_NEW_FORMAT|tag;
117
118     if(out->length < 192)
119         out->buf[1]=out->length;
120     else if(out->length < 8384)
121         {
122         out->buf[1]=((out->length-192) >> 8)+192;
123         out->buf[2]=out->length-192;
124         }
125     else
126         {
127         out->buf[1]=0xff;
128         out->buf[2]=out->length >> 24;
129         out->buf[3]=out->length >> 16;
130         out->buf[4]=out->length >> 8;
131         out->buf[5]=out->length;
132         }
133
134     out->length+=extra+1;
135     }
136
137 ops_memory_t *ops_memory_new()
138     { return ops_mallocz(sizeof(ops_memory_t)); }
139
140 void ops_memory_free(ops_memory_t *mem)
141     {
142     ops_memory_release(mem);
143     free(mem);
144     }
145
146 size_t ops_memory_get_length(const ops_memory_t *mem)
147     { return mem->length; }
148
149 void *ops_memory_get_data(ops_memory_t *mem)
150     { return mem->buf; }
Note: See TracBrowser for help on using the browser.