1 // -*- Mode: C++; -*-
2 //                            Package   : omniORB2
3 // codeSetsImpl.h             Created on: 23/10/2000
4 //                            Author    : Duncan Grisby (dpg1)
5 //
6 //    Copyright (C) 2000 AT&T Laboratories, Cambridge
7 //
8 //    This file is part of the omniORB library
9 //
10 //    The omniORB library is free software; you can redistribute it and/or
11 //    modify it under the terms of the GNU Lesser General Public
12 //    License as published by the Free Software Foundation; either
13 //    version 2.1 of the License, or (at your option) any later version.
14 //
15 //    This library is distributed in the hope that it will be useful,
16 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
17 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 //    Lesser General Public License for more details.
19 //
20 //    You should have received a copy of the GNU Lesser General Public
21 //    License along with this library. If not, see http://www.gnu.org/licenses/
22 //
23 //
24 // Description:
25 //	*** PROPRIETARY INTERFACE ***
26 //
27 
28 #ifndef __CODESETUTIL_H__
29 #define __CODESETUTIL_H__
30 
31 #include <omniORB4/IOP_S.h>
32 #include <exceptiondefs.h>
33 #include <giopStream.h>
34 #include <giopStrand.h>
35 #include <giopRope.h>
36 #include <GIOP_S.h>
37 #include <GIOP_C.h>
38 
39 #ifdef _core_attr
40 # error "A local CPP macro _core_attr has already been defined."
41 #endif
42 
43 #if defined(_OMNIORB_LIBRARY)
44 #     define _core_attr
45 #else
46 #     define _core_attr _OMNIORB_NTDLL_IMPORT
47 #endif
48 
OMNI_NAMESPACE_BEGIN(omni)49 OMNI_NAMESPACE_BEGIN(omni)
50 
51 class omniCodeSetUtil {
52 public:
53 
54   static _core_attr const GIOP::Version GIOP10;
55   static _core_attr const GIOP::Version GIOP11;
56   static _core_attr const GIOP::Version GIOP12;
57 
58   //
59   // Memory management
60   //
61 
62   static inline char* allocC(_CORBA_ULong len) {
63     char* buf = _CORBA_String_helper::alloc(len - 1);
64     if (!buf) OMNIORB_THROW(NO_MEMORY, 0, CORBA::COMPLETED_MAYBE);
65     return buf;
66   }
67 
68   static inline void freeC(char* buf) {
69     _CORBA_String_helper::dealloc(buf);
70   }
71 
72   static inline char* reallocC(char*        oldbuf,
73 			       _CORBA_ULong oldlen,
74 			       _CORBA_ULong newlen)
75   {
76     char* newbuf = allocC(newlen);
77     for (_CORBA_ULong i=0; i < oldlen; i++) newbuf[i] = oldbuf[i];
78     freeC(oldbuf);
79     return newbuf;
80   }
81 
82   static inline omniCodeSet::UniChar* allocU(_CORBA_ULong len) {
83 #if (SIZEOF_WCHAR == 2)
84     omniCodeSet::UniChar* buf = _CORBA_WString_helper::alloc(len - 1);
85 #else
86     omniCodeSet::UniChar* buf = new omniCodeSet::UniChar[len];
87 #endif
88     if (!buf) OMNIORB_THROW(NO_MEMORY, 0, CORBA::COMPLETED_MAYBE);
89     return buf;
90   }
91 
92   static inline void freeU(omniCodeSet::UniChar* buf) {
93 #if (SIZEOF_WCHAR == 2)
94     _CORBA_WString_helper::dealloc(buf);
95 #else
96     delete [] buf;
97 #endif
98   }
99 
100   static inline omniCodeSet::UniChar* reallocU(omniCodeSet::UniChar* oldbuf,
101 					       _CORBA_ULong   oldlen,
102 					       _CORBA_ULong   newlen)
103   {
104     omniCodeSet::UniChar* newbuf = allocU(newlen);
105     for (_CORBA_ULong i=0; i < oldlen; i++) newbuf[i] = oldbuf[i];
106     freeU(oldbuf);
107     return newbuf;
108   }
109 
110   static inline _CORBA_WChar* allocW(_CORBA_ULong len) {
111     _CORBA_WChar* buf = _CORBA_WString_helper::alloc(len - 1);
112     if (!buf) OMNIORB_THROW(NO_MEMORY, 0, CORBA::COMPLETED_MAYBE);
113     return buf;
114   }
115 
116   static inline void freeW(_CORBA_WChar* buf) {
117     _CORBA_WString_helper::dealloc(buf);
118   }
119 
120   static inline _CORBA_WChar* reallocW(_CORBA_WChar* oldbuf,
121 				       _CORBA_ULong  oldlen,
122 				       _CORBA_ULong  newlen)
123   {
124     _CORBA_WChar* newbuf = allocW(newlen);
125     for (_CORBA_ULong i=0; i < oldlen; i++) newbuf[i] = oldbuf[i];
126     freeW(oldbuf);
127     return newbuf;
128   }
129 
130   //
131   // Memory buffers
132   //
133 
134   class BufferC {
135   public:
136     inline BufferC(_CORBA_ULong len = 32) : pd_i(0) {
137       pd_len = len;
138       pd_buf = allocC(len);
139     }
140     inline ~BufferC() {
141       if (pd_buf) freeC(pd_buf);
142     }
143     inline void insert(_CORBA_Char c) {
144       if (pd_i >= pd_len) {
145 	_CORBA_ULong newlen = pd_len * 2;
146 	pd_buf = reallocC(pd_buf, pd_len, newlen);
147 	pd_len = newlen;
148       }
149       pd_buf[pd_i++] = c;
150     }
151     inline _CORBA_ULong length() { return pd_i; }
152     inline char*        buffer() { return pd_buf; }
153     inline char* extract() {
154       char* buf = pd_buf;
155       pd_buf = 0;
156       return buf;
157     }
158   private:
159     _CORBA_ULong pd_i;
160     _CORBA_ULong pd_len;
161     char*        pd_buf;
162   };
163 
164   class BufferU {
165   public:
166     inline BufferU(_CORBA_ULong len = 32) : pd_i(0) {
167       pd_len = len;
168       pd_buf = allocU(len);
169     }
170     inline ~BufferU() {
171       if (pd_buf) freeU(pd_buf);
172     }
173     inline void insert(omniCodeSet::UniChar c) {
174       if (pd_i >= pd_len) {
175 	_CORBA_ULong newlen = pd_len * 2;
176 	pd_buf = reallocU(pd_buf, pd_len, newlen);
177 	pd_len = newlen;
178       }
179       pd_buf[pd_i++] = c;
180     }
181     inline _CORBA_ULong          length() { return pd_i; }
182     inline omniCodeSet::UniChar* buffer() { return pd_buf; }
183     inline omniCodeSet::UniChar* extract() {
184       omniCodeSet::UniChar* buf = pd_buf;
185       pd_buf = 0;
186       return buf;
187     }
188   private:
189     _CORBA_ULong          pd_i;
190     _CORBA_ULong          pd_len;
191     omniCodeSet::UniChar* pd_buf;
192   };
193 
194   class BufferW {
195   public:
196     inline BufferW(_CORBA_ULong len = 32) : pd_i(0) {
197       pd_len = len;
198       pd_buf = allocW(len);
199     }
200     inline ~BufferW() {
201       if (pd_buf) freeW(pd_buf);
202     }
203     inline void insert(_CORBA_ULong c) {
204       if (pd_i >= pd_len) {
205 	_CORBA_ULong newlen = pd_len * 2;
206 	pd_buf = reallocW(pd_buf, pd_len, newlen);
207 	pd_len = newlen;
208       }
209       pd_buf[pd_i++] = (_CORBA_WChar)c;
210     }
211     inline _CORBA_ULong  length() { return pd_i; }
212     inline _CORBA_WChar* buffer() { return pd_buf; }
213     inline _CORBA_WChar* extract() {
214       _CORBA_WChar* buf = pd_buf;
215       pd_buf = 0;
216       return buf;
217     }
218   private:
219     _CORBA_ULong  pd_i;
220     _CORBA_ULong  pd_len;
221     _CORBA_WChar* pd_buf;
222   };
223 
224   //
225   // Memory holders
226   //
227 
228   class HolderC {
229   public:
230     inline HolderC(char* buf) : pd_buf(buf) {}
231     inline ~HolderC() { if (pd_buf) freeC(pd_buf); }
232     inline void drop() { pd_buf = 0; }
233   private:
234     char* pd_buf;
235   };
236 
237   class HolderU {
238   public:
239     inline HolderU(omniCodeSet::UniChar* buf) : pd_buf(buf) {}
240     inline ~HolderU() { if (pd_buf) freeU(pd_buf); }
241     inline void drop() { pd_buf = 0; }
242   private:
243     omniCodeSet::UniChar* pd_buf;
244   };
245 
246   class HolderW {
247   public:
248     inline HolderW(_CORBA_WChar* buf) : pd_buf(buf) {}
249     inline ~HolderW() { if (pd_buf) freeW(pd_buf); }
250     inline void drop() { pd_buf = 0; }
251   private:
252     _CORBA_WChar* pd_buf;
253   };
254 };
255 
256 // These macros check there is a wchar transmission code set and, if
257 // not, throw the appropriate exceptions.
258 
259 #define OMNIORB_CHECK_TCS_W_FOR_UNMARSHAL(tcs, stream) \
260 do { \
261   if (!tcs) { \
262     giopStream* gs = giopStream::downcast(&stream); \
263     if (gs) { \
264       GIOP::Version v = gs->version(); \
265       if (v.major == 1 && v.minor == 0) { \
266         if (GIOP_S::downcast(&stream)) \
267           OMNIORB_THROW(MARSHAL, MARSHAL_WCharSentByGIOP10Client, \
268                         (CORBA::CompletionStatus)stream.completion()); \
269         if (GIOP_C::downcast(&stream)) \
270           OMNIORB_THROW(MARSHAL, MARSHAL_WCharSentByGIOP10Server, \
271                         (CORBA::CompletionStatus)stream.completion()); \
272       } \
273     } \
274     if (GIOP_C::downcast(&stream))                                 \
275       OMNIORB_THROW(INV_OBJREF, INV_OBJREF_WCharNotSupported,      \
276                     (CORBA::CompletionStatus)stream.completion()); \
277     OMNIORB_THROW(BAD_PARAM,BAD_PARAM_WCharTCSNotKnown,            \
278 		  (CORBA::CompletionStatus)stream.completion());   \
279   } \
280 } while(0)
281 
282 #define OMNIORB_CHECK_TCS_W_FOR_MARSHAL(tcs, stream) \
283 do { \
284   if (!tcs) { \
285     if (GIOP_C::downcast(&stream))                                 \
286       OMNIORB_THROW(INV_OBJREF, INV_OBJREF_WCharNotSupported,      \
287                     (CORBA::CompletionStatus)stream.completion()); \
288     OMNIORB_THROW(BAD_PARAM,BAD_PARAM_WCharTCSNotKnown,            \
289                   (CORBA::CompletionStatus)stream.completion());   \
290   } \
291 } while(0)
292 
293 
294 OMNI_NAMESPACE_END(omni)
295 
296 #undef _core_attr
297 
298 #endif // __CODESETUTIL_H__
299