2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
10 #include "EbmlWriter.h"
15 #include "EbmlBufferWriter.h"
17 #define LITERALU64(n) n
19 #define LITERALU64(n) n##LLU
22 void Ebml_WriteLen(EbmlGlobal
*glob
, int64_t val
) {
23 /* TODO check and make sure we are not > than 0x0100000000000000LLU */
24 unsigned char size
= 8; /* size in bytes to output */
26 /* mask to compare for byte size */
27 int64_t minVal
= 0xff;
29 for (size
= 1; size
< 8; size
++) {
33 minVal
= (minVal
<< 7);
36 val
|= (((uint64_t)0x80) << ((size
- 1) * 7));
38 Ebml_Serialize(glob
, (void *) &val
, sizeof(val
), size
);
41 void Ebml_WriteString(EbmlGlobal
*glob
, const char *str
) {
42 const size_t size_
= strlen(str
);
43 const uint64_t size
= size_
;
44 Ebml_WriteLen(glob
, size
);
45 /* TODO: it's not clear from the spec whether the nul terminator
46 * should be serialized too. For now we omit the null terminator.
48 Ebml_Write(glob
, str
, (unsigned long)size
);
51 void Ebml_WriteUTF8(EbmlGlobal
*glob
, const wchar_t *wstr
) {
52 const size_t strlen
= wcslen(wstr
);
54 /* TODO: it's not clear from the spec whether the nul terminator
55 * should be serialized too. For now we include it.
57 const uint64_t size
= strlen
;
59 Ebml_WriteLen(glob
, size
);
60 Ebml_Write(glob
, wstr
, (unsigned long)size
);
63 void Ebml_WriteID(EbmlGlobal
*glob
, unsigned long class_id
) {
66 if (class_id
>= 0x01000000)
68 else if (class_id
>= 0x00010000)
70 else if (class_id
>= 0x00000100)
75 Ebml_Serialize(glob
, (void *)&class_id
, sizeof(class_id
), len
);
78 void Ebml_SerializeUnsigned32(EbmlGlobal
*glob
, unsigned long class_id
, uint32_t ui
) {
79 unsigned char sizeSerialized
= 8 | 0x80;
80 Ebml_WriteID(glob
, class_id
);
81 Ebml_Serialize(glob
, &sizeSerialized
, sizeof(sizeSerialized
), 1);
82 Ebml_Serialize(glob
, &ui
, sizeof(ui
), 4);
85 void Ebml_SerializeUnsigned64(EbmlGlobal
*glob
, unsigned long class_id
, uint64_t ui
) {
86 unsigned char sizeSerialized
= 8 | 0x80;
87 Ebml_WriteID(glob
, class_id
);
88 Ebml_Serialize(glob
, &sizeSerialized
, sizeof(sizeSerialized
), 1);
89 Ebml_Serialize(glob
, &ui
, sizeof(ui
), 8);
92 void Ebml_SerializeUnsigned(EbmlGlobal
*glob
, unsigned long class_id
, unsigned long ui
) {
93 unsigned char size
= 8; /* size in bytes to output */
94 unsigned char sizeSerialized
= 0;
97 Ebml_WriteID(glob
, class_id
);
98 minVal
= 0x7fLU
; /* mask to compare for byte size */
100 for (size
= 1; size
< 4; size
++) {
108 sizeSerialized
= 0x80 | size
;
109 Ebml_Serialize(glob
, &sizeSerialized
, sizeof(sizeSerialized
), 1);
110 Ebml_Serialize(glob
, &ui
, sizeof(ui
), size
);
112 /* TODO: perhaps this is a poor name for this id serializer helper function */
113 void Ebml_SerializeBinary(EbmlGlobal
*glob
, unsigned long class_id
, unsigned long bin
) {
115 for (size
= 4; size
> 1; size
--) {
116 if (bin
& (unsigned int)0x000000ff << ((size
- 1) * 8))
119 Ebml_WriteID(glob
, class_id
);
120 Ebml_WriteLen(glob
, size
);
121 Ebml_WriteID(glob
, bin
);
124 void Ebml_SerializeFloat(EbmlGlobal
*glob
, unsigned long class_id
, double d
) {
125 unsigned char len
= 0x88;
127 Ebml_WriteID(glob
, class_id
);
128 Ebml_Serialize(glob
, &len
, sizeof(len
), 1);
129 Ebml_Serialize(glob
, &d
, sizeof(d
), 8);
132 void Ebml_WriteSigned16(EbmlGlobal
*glob
, short val
) {
133 signed long out
= ((val
& 0x003FFFFF) | 0x00200000) << 8;
134 Ebml_Serialize(glob
, &out
, sizeof(out
), 3);
137 void Ebml_SerializeString(EbmlGlobal
*glob
, unsigned long class_id
, const char *s
) {
138 Ebml_WriteID(glob
, class_id
);
139 Ebml_WriteString(glob
, s
);
142 void Ebml_SerializeUTF8(EbmlGlobal
*glob
, unsigned long class_id
, wchar_t *s
) {
143 Ebml_WriteID(glob
, class_id
);
144 Ebml_WriteUTF8(glob
, s
);
147 void Ebml_SerializeData(EbmlGlobal
*glob
, unsigned long class_id
, unsigned char *data
, unsigned long data_length
) {
148 Ebml_WriteID(glob
, class_id
);
149 Ebml_WriteLen(glob
, data_length
);
150 Ebml_Write(glob
, data
, data_length
);
153 void Ebml_WriteVoid(EbmlGlobal
*glob
, unsigned long vSize
) {
154 unsigned char tmp
= 0;
157 Ebml_WriteID(glob
, 0xEC);
158 Ebml_WriteLen(glob
, vSize
);
160 for (i
= 0; i
< vSize
; i
++) {
161 Ebml_Write(glob
, &tmp
, 1);
165 /* TODO Serialize Date */