Fix build error with GCC6
[profile/ivi/log4cxx.git] / src / main / cpp / objectoutputstream.cpp
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #if defined(_MSC_VER)
18 #pragma warning ( disable: 4231 4251 4275 4786 )
19 #endif
20
21 #include <log4cxx/logstring.h>
22 #include <log4cxx/helpers/objectoutputstream.h>
23 #include <log4cxx/helpers/bytebuffer.h>
24 #include <log4cxx/helpers/outputstream.h>
25 #include <log4cxx/helpers/charsetencoder.h>
26 #include "apr_pools.h"
27
28 using namespace log4cxx;
29 using namespace log4cxx::helpers;
30
31 IMPLEMENT_LOG4CXX_OBJECT(ObjectOutputStream)
32
33 ObjectOutputStream::ObjectOutputStream(OutputStreamPtr outputStream, Pool& p)
34      : os(outputStream) , 
35        utf8Encoder(CharsetEncoder::getUTF8Encoder()), 
36        objectHandle(0x7E0000),
37        classDescriptions(new ClassDescriptionMap())
38 {
39    unsigned char start[] = { 0xAC, 0xED, 0x00, 0x05 };
40    ByteBuffer buf((char*)start, sizeof(start));
41    os->write(buf, p);
42 }
43
44 ObjectOutputStream::~ObjectOutputStream() {
45     delete classDescriptions;
46 }
47
48 void ObjectOutputStream::close(Pool& p) {
49     os->close(p);
50 }
51
52 void ObjectOutputStream::flush(Pool& p) {
53     os->flush(p);
54 }
55
56 void ObjectOutputStream::writeObject(const LogString& val, Pool& p) {
57    objectHandle++;
58    writeByte(TC_STRING, p);
59    char bytes[2];
60 #if LOG4CXX_LOGCHAR_IS_UTF8
61     size_t len = val.size();
62     ByteBuffer dataBuf(const_cast<char*>(val.data()), val.size()); 
63 #else
64     size_t maxSize = 6 * val.size();
65     char* data = p.pstralloc(maxSize);
66     ByteBuffer dataBuf(data, maxSize);
67     LogString::const_iterator iter(val.begin());
68     utf8Encoder->encode(val, iter, dataBuf); 
69     dataBuf.flip();
70     size_t len = dataBuf.limit();
71 #endif
72    bytes[1] = (char) (len & 0xFF);
73    bytes[0] = (char) ((len >> 8) & 0xFF);
74    ByteBuffer lenBuf(bytes, sizeof(bytes));
75    os->write(lenBuf, p);
76    os->write(dataBuf, p);
77 }
78
79
80 void ObjectOutputStream::writeObject(const MDC::Map& val, Pool& p) {
81     //
82     //  TC_OBJECT and the classDesc for java.util.Hashtable
83     //
84     unsigned char prolog[] = {
85         0x72, 0x00, 0x13, 0x6A, 0x61, 0x76, 0x61, 
86         0x2E, 0x75, 0x74, 0x69, 0x6C, 0x2E, 0x48, 0x61, 
87         0x73, 0x68, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x13, 
88         0xBB, 0x0F, 0x25, 0x21, 0x4A, 0xE4, 0xB8, 0x03, 
89         0x00, 0x02, 0x46, 0x00, 0x0A, 0x6C, 0x6F, 0x61, 
90         0x64, 0x46, 0x61, 0x63, 0x74, 0x6F, 0x72, 0x49, 
91         0x00, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 
92         0x6F, 0x6C, 0x64, 0x78, 0x70  };
93     writeProlog("java.util.Hashtable", 1, (char *) prolog, sizeof(prolog), p);
94     //
95     //   loadFactor = 0.75, threshold = 5, blockdata start, buckets.size = 7
96     char data[] = { 0x3F, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 
97         TC_BLOCKDATA, 0x08, 0x00, 0x00, 0x00, 0x07 };
98     ByteBuffer dataBuf(data, sizeof(data));
99     os->write(dataBuf, p);
100     char size[4];
101     size_t sz = val.size();
102     size[3] = (char) (sz & 0xFF);
103     size[2] = (char) ((sz >> 8) & 0xFF);
104     size[1] = (char) ((sz >> 16) & 0xFF);
105     size[0] = (char) ((sz >> 24) & 0xFF);
106     ByteBuffer sizeBuf(size, sizeof(size));
107     os->write(sizeBuf, p);
108     for(MDC::Map::const_iterator iter = val.begin();
109         iter != val.end();
110         iter++) {
111         writeObject(iter->first, p);
112         writeObject(iter->second, p);
113     }
114     writeByte(TC_ENDBLOCKDATA, p);
115 }
116
117 void ObjectOutputStream::writeUTFString(const std::string& val, Pool& p) {
118     char bytes[3];
119     size_t len = val.size();
120     ByteBuffer dataBuf(const_cast<char*>(val.data()), val.size()); 
121    objectHandle++;
122    bytes[0] = 0x74;
123    bytes[1] = (char) ((len >> 8) & 0xFF);
124    bytes[2] = (char) (len & 0xFF);
125    ByteBuffer lenBuf(bytes, sizeof(bytes));
126    os->write(lenBuf, p);
127    os->write(dataBuf, p);
128 }
129
130
131
132 void ObjectOutputStream::writeByte(char val, Pool& p) {
133    ByteBuffer buf(&val, 1);
134    os->write(buf, p);
135 }
136
137 void ObjectOutputStream::writeInt(int val, Pool& p) {
138    char bytes[4];
139    bytes[3] = (char) (val & 0xFF);
140    bytes[2] = (char) ((val >> 8) & 0xFF);
141    bytes[1] = (char) ((val >> 16) & 0xFF);
142    bytes[0] = (char) ((val >> 24) & 0xFF);
143    ByteBuffer buf(bytes, sizeof(bytes));
144    os->write(buf, p);
145 }
146
147 void ObjectOutputStream::writeLong(log4cxx_time_t val, Pool& p) {
148    char bytes[8];
149    bytes[7] = (char) (val & 0xFF);
150    bytes[6] = (char) ((val >> 8) & 0xFF);
151    bytes[5] = (char) ((val >> 16) & 0xFF);
152    bytes[4] = (char) ((val >> 24) & 0xFF);
153    bytes[3] = (char) ((val >> 32) & 0xFF);
154    bytes[2] = (char) ((val >> 40) & 0xFF);
155    bytes[1] = (char) ((val >> 48) & 0xFF);
156    bytes[0] = (char) ((val >> 56) & 0xFF);
157    ByteBuffer buf(bytes, sizeof(bytes));
158    os->write(buf, p);
159 }
160
161 void ObjectOutputStream::writeBytes(const char* bytes, size_t len, Pool& p) {
162    ByteBuffer buf(const_cast<char*>(bytes), len);
163    os->write(buf, p);
164 }
165
166 void ObjectOutputStream::writeNull(Pool& p) {
167    writeByte(TC_NULL, p);
168 }
169
170 void ObjectOutputStream::writeProlog(const char* className,
171                         int classDescIncrement,
172                         char* classDesc,
173                         size_t len,
174                         Pool& p) {
175     ClassDescriptionMap::const_iterator match = classDescriptions->find(className);
176     if (match != classDescriptions->end()) {
177         char bytes[6];
178         bytes[0] = TC_OBJECT;
179         bytes[1] = TC_REFERENCE;
180         bytes[2] = (char) ((match->second >> 24) & 0xFF);
181         bytes[3] = (char) ((match->second >> 16) & 0xFF);
182         bytes[4] = (char) ((match->second >> 8) & 0xFF);
183         bytes[5] = (char) (match->second & 0xFF);
184         ByteBuffer buf(bytes, sizeof(bytes));
185         os->write(buf, p);
186         objectHandle++;
187     } else {
188         classDescriptions->insert(ClassDescriptionMap::value_type(className, objectHandle));
189         writeByte(TC_OBJECT, p);
190         ByteBuffer buf(classDesc, len);
191         os->write(buf, p);
192         objectHandle += (classDescIncrement + 1);
193     }
194