OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. | |
3 * | |
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. | |
9 */ | |
10 #include "EbmlWriter.h" | |
11 #include <stdlib.h> | |
12 #include <wchar.h> | |
13 #include <string.h> | |
14 #include <limits.h> | |
15 #if defined(_MSC_VER) | |
16 #define LITERALU64(n) n | |
17 #else | |
18 #define LITERALU64(n) n##LLU | |
19 #endif | |
20 | |
21 void Ebml_WriteLen(EbmlGlobal *glob, int64_t val) { | |
22 /* TODO check and make sure we are not > than 0x0100000000000000LLU */ | |
23 unsigned char size = 8; /* size in bytes to output */ | |
24 | |
25 /* mask to compare for byte size */ | |
26 int64_t minVal = 0xff; | |
27 | |
28 for (size = 1; size < 8; size ++) { | |
29 if (val < minVal) | |
30 break; | |
31 | |
32 minVal = (minVal << 7); | |
33 } | |
34 | |
35 val |= (((uint64_t)0x80) << ((size - 1) * 7)); | |
36 | |
37 Ebml_Serialize(glob, (void *) &val, sizeof(val), size); | |
38 } | |
39 | |
40 void Ebml_WriteString(EbmlGlobal *glob, const char *str) { | |
41 const size_t size_ = strlen(str); | |
42 const uint64_t size = size_; | |
43 Ebml_WriteLen(glob, size); | |
44 /* TODO: it's not clear from the spec whether the nul terminator | |
45 * should be serialized too. For now we omit the null terminator. | |
46 */ | |
47 Ebml_Write(glob, str, (unsigned long)size); | |
48 } | |
49 | |
50 void Ebml_WriteUTF8(EbmlGlobal *glob, const wchar_t *wstr) { | |
51 const size_t strlen = wcslen(wstr); | |
52 | |
53 /* TODO: it's not clear from the spec whether the nul terminator | |
54 * should be serialized too. For now we include it. | |
55 */ | |
56 const uint64_t size = strlen; | |
57 | |
58 Ebml_WriteLen(glob, size); | |
59 Ebml_Write(glob, wstr, (unsigned long)size); | |
60 } | |
61 | |
62 void Ebml_WriteID(EbmlGlobal *glob, unsigned long class_id) { | |
63 int len; | |
64 | |
65 if (class_id >= 0x01000000) | |
66 len = 4; | |
67 else if (class_id >= 0x00010000) | |
68 len = 3; | |
69 else if (class_id >= 0x00000100) | |
70 len = 2; | |
71 else | |
72 len = 1; | |
73 | |
74 Ebml_Serialize(glob, (void *)&class_id, sizeof(class_id), len); | |
75 } | |
76 | |
77 void Ebml_SerializeUnsigned64(EbmlGlobal *glob, unsigned long class_id, uint64_t
ui) { | |
78 unsigned char sizeSerialized = 8 | 0x80; | |
79 Ebml_WriteID(glob, class_id); | |
80 Ebml_Serialize(glob, &sizeSerialized, sizeof(sizeSerialized), 1); | |
81 Ebml_Serialize(glob, &ui, sizeof(ui), 8); | |
82 } | |
83 | |
84 void Ebml_SerializeUnsigned(EbmlGlobal *glob, unsigned long class_id, unsigned l
ong ui) { | |
85 unsigned char size = 8; /* size in bytes to output */ | |
86 unsigned char sizeSerialized = 0; | |
87 unsigned long minVal; | |
88 | |
89 Ebml_WriteID(glob, class_id); | |
90 minVal = 0x7fLU; /* mask to compare for byte size */ | |
91 | |
92 for (size = 1; size < 4; size ++) { | |
93 if (ui < minVal) { | |
94 break; | |
95 } | |
96 | |
97 minVal <<= 7; | |
98 } | |
99 | |
100 sizeSerialized = 0x80 | size; | |
101 Ebml_Serialize(glob, &sizeSerialized, sizeof(sizeSerialized), 1); | |
102 Ebml_Serialize(glob, &ui, sizeof(ui), size); | |
103 } | |
104 /* TODO: perhaps this is a poor name for this id serializer helper function */ | |
105 void Ebml_SerializeBinary(EbmlGlobal *glob, unsigned long class_id, unsigned lon
g bin) { | |
106 int size; | |
107 for (size = 4; size > 1; size--) { | |
108 if (bin & (unsigned int)0x000000ff << ((size - 1) * 8)) | |
109 break; | |
110 } | |
111 Ebml_WriteID(glob, class_id); | |
112 Ebml_WriteLen(glob, size); | |
113 Ebml_WriteID(glob, bin); | |
114 } | |
115 | |
116 void Ebml_SerializeFloat(EbmlGlobal *glob, unsigned long class_id, double d) { | |
117 unsigned char len = 0x88; | |
118 | |
119 Ebml_WriteID(glob, class_id); | |
120 Ebml_Serialize(glob, &len, sizeof(len), 1); | |
121 Ebml_Serialize(glob, &d, sizeof(d), 8); | |
122 } | |
123 | |
124 void Ebml_WriteSigned16(EbmlGlobal *glob, short val) { | |
125 signed long out = ((val & 0x003FFFFF) | 0x00200000) << 8; | |
126 Ebml_Serialize(glob, &out, sizeof(out), 3); | |
127 } | |
128 | |
129 void Ebml_SerializeString(EbmlGlobal *glob, unsigned long class_id, const char *
s) { | |
130 Ebml_WriteID(glob, class_id); | |
131 Ebml_WriteString(glob, s); | |
132 } | |
133 | |
134 void Ebml_SerializeUTF8(EbmlGlobal *glob, unsigned long class_id, wchar_t *s) { | |
135 Ebml_WriteID(glob, class_id); | |
136 Ebml_WriteUTF8(glob, s); | |
137 } | |
138 | |
139 void Ebml_SerializeData(EbmlGlobal *glob, unsigned long class_id, unsigned char
*data, unsigned long data_length) { | |
140 Ebml_WriteID(glob, class_id); | |
141 Ebml_WriteLen(glob, data_length); | |
142 Ebml_Write(glob, data, data_length); | |
143 } | |
144 | |
145 void Ebml_WriteVoid(EbmlGlobal *glob, unsigned long vSize) { | |
146 unsigned char tmp = 0; | |
147 unsigned long i = 0; | |
148 | |
149 Ebml_WriteID(glob, 0xEC); | |
150 Ebml_WriteLen(glob, vSize); | |
151 | |
152 for (i = 0; i < vSize; i++) { | |
153 Ebml_Write(glob, &tmp, 1); | |
154 } | |
155 } | |
156 | |
157 /* TODO Serialize Date */ | |
OLD | NEW |