2 #include "git-compat-util.h"
4 void encode_uint32(unsigned char *ptr
, uint32_t value
)
6 ptr
[0] = (unsigned char)(value
>> 24);
7 ptr
[1] = (unsigned char)(value
>> 16);
8 ptr
[2] = (unsigned char)(value
>> 8);
9 ptr
[3] = (unsigned char)(value
);
12 /* Base64 character value */
13 static int char_value(unsigned char ch
)
15 if (ch
>= 'A' && ch
<= 'Z')
17 if (ch
>= 'a' && ch
<= 'z')
19 if (ch
>= '0' && ch
<= '9')
28 /* Decode Base64 chunk. */
29 unsigned char *decode_base64_chunk(const unsigned char *chunk
,
30 size_t chunk_len
, size_t *key_len
)
33 unsigned blockmod
= 0;
37 ret
= xmalloc((chunk_len
+ 3) / 4 * 3);
40 for(i
= 0; i
< chunk_len
; i
++) {
41 buf
[blockmod
] = char_value(chunk
[i
]);
42 if (buf
[blockmod
] >= 0)
47 int v
= (buf
[0] << 18) | (buf
[1] << 12) |
48 (buf
[2] << 6) | buf
[3];
49 ret
[(*key_len
)++] = (unsigned char)(v
>> 16);
50 ret
[(*key_len
)++] = (unsigned char)(v
>> 8);
51 ret
[(*key_len
)++] = (unsigned char)(v
);
53 buf
[0] = buf
[1] = buf
[2] = buf
[3] = 0;
57 int v
= (buf
[0] << 18) | (buf
[1] << 12) |
58 (buf
[2] << 6) | buf
[3];
60 ret
[(*key_len
)++] = (unsigned char)(v
>> 16);
62 ret
[(*key_len
)++] = (unsigned char)(v
>> 8);
67 /* Return address of next (nonempty) line, or NULL if none. */
68 const unsigned char *next_line(const unsigned char *blob
,
71 while (*blob
!= '\r' && *blob
!= '\n') {
77 while (*blob
== '\r' || *blob
== '\n') {
87 #define STATUS_HEADER 1
88 #define STATUS_CONTINUE 2
90 #define STATUS_EOL_CONTINUE 4
92 /* Find start of base64 blob. */
93 const unsigned char *base64_blob_start(const unsigned char *blob
,
96 int status
= STATUS_INIT
;
97 const unsigned char *line_start
;
101 size_start
= *remaining
;
106 if (!*remaining
|| *blob
== '\r' || *blob
== '\n') {
107 /* Back off to start of line. */
109 *remaining
= size_start
;
113 status
= STATUS_HEADER
;
120 if (*blob
== '\r' || *blob
== '\n')
123 status
= STATUS_CONTINUE
;
125 case STATUS_CONTINUE
:
130 if (*blob
== '\r' || *blob
== '\n')
131 status
= STATUS_EOL_CONTINUE
;
133 status
= STATUS_HEADER
;
140 if (*blob
!= '\r' && *blob
!= '\n') {
141 /* Mark line start and back off by one. */
143 size_start
= *remaining
;
146 status
= STATUS_INIT
;
149 case STATUS_EOL_CONTINUE
:
154 if (*blob
!= '\r' && *blob
!= '\n') {
155 /* Mark line start and back off by one. */
157 size_start
= *remaining
;
160 status
= STATUS_HEADER
;