]> git.vomp.tv Git - vompserver.git/blob - responsepacket.c
15 years that line of code has been waiting to crash
[vompserver.git] / responsepacket.c
1 /*
2     Copyright 2007 Chris Tallon
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 */
20
21 #include <arpa/inet.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include "responsepacket.h"
26 #include "log.h"
27
28 /* Packet format for an RR channel response:
29
30 4 bytes = channel ID = 1 (request/response channel)
31 4 bytes = request ID (from serialNumber)
32 4 bytes = length of the rest of the packet
33 ? bytes = rest of packet. depends on packet
34 */
35
36 ResponsePacket::ResponsePacket()
37 {
38   buffer = NULL;
39   bufSize = 0;
40   bufUsed = 0;
41 }
42
43 ResponsePacket::~ResponsePacket()
44 {
45   if (buffer) free(buffer);
46 }
47
48 bool ResponsePacket::init(ULONG requestID)
49 {
50   if (buffer) return false;
51   
52   bufSize = 512;
53   buffer = (UCHAR*)malloc(bufSize);
54   if (!buffer) return false;
55   
56   *(ULONG*)&buffer[0] = htonl(1); // RR channel
57   *(ULONG*)&buffer[4] = htonl(requestID);
58   *(ULONG*)&buffer[userDataLenPos] = 0;
59   bufUsed = headerLength;
60
61   return true;
62 }
63
64 void ResponsePacket::finalise()
65 {
66   *(ULONG*)&buffer[userDataLenPos] = htonl(bufUsed - headerLength);
67   //Log::getInstance()->log("Client", Log::DEBUG, "RP finalise %lu", bufUsed - headerLength);
68 }
69
70 bool ResponsePacket::copyin(const UCHAR* src, ULONG len)
71 {
72   if (!checkExtend(len)) return false;
73   memcpy(buffer + bufUsed, src, len);
74   bufUsed += len;
75   return true;
76 }
77
78 bool ResponsePacket::addString(const char* string)
79 {
80   ULONG len = strlen(string) + 1;
81   if (!checkExtend(len)) return false;
82   memcpy(buffer + bufUsed, string, len);
83   bufUsed += len;
84   return true;
85 }
86
87 bool ResponsePacket::addULONG(ULONG ul)
88 {
89   if (!checkExtend(sizeof(ULONG))) return false;
90   *(ULONG*)&buffer[bufUsed] = htonl(ul);
91   bufUsed += sizeof(ULONG);
92   return true;
93 }  
94
95 bool ResponsePacket::addUCHAR(UCHAR c)
96 {
97   if (!checkExtend(sizeof(UCHAR))) return false;
98   buffer[bufUsed] = c;
99   bufUsed += sizeof(UCHAR);
100   return true;
101 }  
102   
103 bool ResponsePacket::addLONG(LONG l)
104 {
105   if (!checkExtend(sizeof(LONG))) return false;
106   *(LONG*)&buffer[bufUsed] = htonl(l);
107   bufUsed += sizeof(LONG);
108   return true;
109 }
110
111 bool ResponsePacket::addULLONG(ULLONG ull)
112 {
113   if (!checkExtend(sizeof(ULLONG))) return false;
114   *(ULLONG*)&buffer[bufUsed] = htonll(ull);
115   bufUsed += sizeof(ULLONG);
116   return true;
117 }
118
119 bool ResponsePacket::adddouble(double d)
120 {
121   if (!checkExtend(sizeof(double))) return false;
122   ULLONG ull;
123   memcpy(&ull,&d,sizeof(double));
124   *(ULLONG*)&buffer[bufUsed] = htonll(ull);
125   bufUsed += sizeof(ULLONG);
126   return true;
127 }
128
129
130 bool ResponsePacket::checkExtend(ULONG by)
131 {
132   if ((bufUsed + by) < bufSize) return true;
133   if (512 > by) by = 512;
134   UCHAR* newBuf = (UCHAR*)realloc(buffer, bufSize + by);
135   if (!newBuf) return false;
136   buffer = newBuf;
137   bufSize += by;
138   return true;
139 }
140
141 ULLONG ResponsePacket::htonll(ULLONG a)
142 {
143   #if BYTE_ORDER == BIG_ENDIAN
144     return a;
145   #else
146     ULLONG b = 0;
147
148     b = ((a << 56) & 0xFF00000000000000ULL)
149       | ((a << 40) & 0x00FF000000000000ULL)
150       | ((a << 24) & 0x0000FF0000000000ULL)
151       | ((a <<  8) & 0x000000FF00000000ULL)
152       | ((a >>  8) & 0x00000000FF000000ULL)
153       | ((a >> 24) & 0x0000000000FF0000ULL)
154       | ((a >> 40) & 0x000000000000FF00ULL)
155       | ((a >> 56) & 0x00000000000000FFULL) ;
156
157     return b;
158   #endif
159 }
160