irods  4.2.8
About: iRODS (the integrated Rule Oriented Data System) is a distributed data-management system for creating data grids, digital libraries, persistent archives, and real-time data systems.
  Fossies Dox: irods-4.2.8.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

packStruct.cpp
Go to the documentation of this file.
1 
4 /* packStruct.c - routine for pack and unfolding C struct
5  */
6 
7 
8 #include "packStruct.h"
9 #include "alignPointer.hpp"
10 #include "rodsLog.h"
11 #include "rcGlobalExtern.h"
12 #include "base64.h"
13 #include "rcMisc.h"
14 
15 #include "irods_pack_table.hpp"
16 #include <iostream>
17 #include <sstream>
18 #include <string>
19 
20 int
21 packStruct( const void *inStruct, bytesBuf_t **packedResult, const char *packInstName,
22  const packInstruct_t *myPackTable, int packFlag, irodsProt_t irodsProt ) {
23  if ( inStruct == NULL || packedResult == NULL || packInstName == NULL ) {
25  "packStruct: Input error. One of the input is NULL" );
27  }
28 
29  /* Initialize the packedOutput */
31 
32  packItem_t rootPackedItem{};
33  rootPackedItem.name = strdup( packInstName );
34  int status = packChildStruct( inStruct, packedOutput, rootPackedItem,
35  myPackTable, 1, packFlag, irodsProt, NULL );
36  free( rootPackedItem.name );
37 
38  if ( status < 0 ) {
39  free( packedOutput.bBuf.buf );
40  return status;
41  }
42 
43  if ( irodsProt == XML_PROT ) {
44  void *outPtr;
45  status = extendPackedOutput( packedOutput, 1, outPtr );
46  if ( SYS_MALLOC_ERR == status ) {
47  return status;
48  }
49 
50  /* add a NULL termination */
51  *static_cast<char*>(outPtr) = '\0';
52  if ( getRodsLogLevel() >= LOG_DEBUG9 ) {
53  printf( "packed XML: \n%s\n", ( char * ) packedOutput.bBuf.buf );
54  }
55  }
56 
57  *packedResult = (bytesBuf_t*)malloc(sizeof(**packedResult));
58  **packedResult = packedOutput.bBuf;
59  return 0;
60 }
61 
62 int
63 unpackStruct( const void *inPackedStr, void **outStruct, const char *packInstName,
64  const packInstruct_t *myPackTable, irodsProt_t irodsProt ) {
65  if ( inPackedStr == NULL || packInstName == NULL ) {
67  "unpackStruct: Input error. One of the input is NULL" );
69  }
70 
71  /* Initialize the unpackedOutput */
73 
74  packItem_t rootPackedItem{};
75  rootPackedItem.name = strdup( packInstName );
76  int status = unpackChildStruct( inPackedStr, unpackedOutput, rootPackedItem,
77  myPackTable, 1, irodsProt, NULL );
78  free( rootPackedItem.name );
79 
80  if ( status < 0 ) {
81  free( unpackedOutput.bBuf.buf );
82  return status;
83  }
84 
85  *outStruct = unpackedOutput.bBuf.buf;
86 
87  return 0;
88 }
89 
90 int
91 parsePackInstruct( const char *packInstruct, packItem_t &packItemHead ) {
92  char buf[MAX_PI_LEN];
93  packItem_t *myPackItem = &packItemHead;
94  packItem_t *prevPackItem = NULL;
95  const char *inptr = packInstruct;
96  int gotTypeCast = 0;
97  int gotItemName = 0;
98 
99  while ( copyStrFromPiBuf( inptr, buf, 0 ) > 0 ) {
100  if ( !myPackItem ) {
101  myPackItem = ( packItem_t* )malloc( sizeof( packItem_t ) );
102  memset( myPackItem, 0, sizeof( packItem_t ) );
103  }
104 
105  if ( strcmp( buf, ";" ) == 0 ) { /* delimiter */
106  if ( gotTypeCast == 0 && gotItemName == 0 ) {
107  /* just an extra ';' */
108  continue;
109  }
110  else if ( gotTypeCast > 0 && gotItemName == 0 ) {
112  "parsePackInstruct: No varName for %s", packInstruct );
113  if ( myPackItem != &packItemHead ) {
114  free( myPackItem );
115  }
117  }
118  /* queue it */
119  gotTypeCast = 0;
120  gotItemName = 0;
121  if ( prevPackItem != NULL ) {
122  prevPackItem->next = myPackItem;
123  myPackItem->prev = prevPackItem;
124  }
125  prevPackItem = myPackItem;
126  myPackItem = NULL;
127  continue;
128  }
129  else if ( strcmp( buf, "%" ) == 0 ) { /* int dependent */
130  /* int dependent type */
131  if ( gotTypeCast > 0 || gotItemName > 0 ) {
133  "parsePackInstruct: % position error for %s", packInstruct );
134  if ( myPackItem != &packItemHead ) {
135  free( myPackItem );
136  }
138  }
139  myPackItem->typeInx = ( packTypeInx_t )packTypeLookup( buf );
140  if ( myPackItem->typeInx < 0 ) {
142  "parsePackInstruct: packTypeLookup failed for %s", buf );
143  if ( myPackItem != &packItemHead ) {
144  free( myPackItem );
145  }
147  }
148  gotTypeCast = 1;
149  int outLen = copyStrFromPiBuf( inptr, buf, 1 );
150  if ( outLen <= 0 ) {
152  "parsePackInstruct: ? No variable following ? for %s",
153  packInstruct );
154  if ( myPackItem != &packItemHead ) {
155  free( myPackItem );
156  }
158  }
159  myPackItem->name = strdup( buf );
160  gotItemName = 1;
161  continue;
162  }
163  else if ( strcmp( buf, "?" ) == 0 ) { /* dependent */
164  /* dependent type */
165  if ( gotTypeCast > 0 || gotItemName > 0 ) {
167  "parsePackInstruct: ? position error for %s", packInstruct );
168  if ( myPackItem != &packItemHead ) {
169  free( myPackItem );
170  }
172  }
173  myPackItem->typeInx = ( packTypeInx_t )packTypeLookup( buf );
174  if ( myPackItem->typeInx < 0 ) {
176  "parsePackInstruct: packTypeLookup failed for %s", buf );
177  if ( myPackItem != &packItemHead ) {
178  free( myPackItem );
179  }
181  }
182  gotTypeCast = 1;
183  int outLen = copyStrFromPiBuf( inptr, buf, 0 );
184  if ( outLen <= 0 ) {
186  "parsePackInstruct: ? No variable following ? for %s",
187  packInstruct );
188  if ( myPackItem != &packItemHead ) {
189  free( myPackItem );
190  }
192  }
193  rstrcpy( myPackItem->strValue, buf, NAME_LEN );
194  continue;
195  }
196  else if ( strcmp( buf, "*" ) == 0 ) { /* pointer */
197  myPackItem->pointerType = A_POINTER;
198  if ( gotTypeCast == 0 || gotItemName > 0 ) {
200  "parsePackInstruct: * position error for %s", packInstruct );
201  if ( myPackItem != &packItemHead ) {
202  free( myPackItem );
203  }
205  }
206  continue;
207  }
208  else if ( strcmp( buf, "#" ) == 0 ) { /* no pack pointer */
209  myPackItem->pointerType = NO_PACK_POINTER;
210  if ( gotTypeCast == 0 || gotItemName > 0 ) {
212  "parsePackInstruct: # position error for %s", packInstruct );
213  if ( myPackItem != &packItemHead ) {
214  free( myPackItem );
215  }
217  }
218  continue;
219  }
220  else if ( strcmp( buf, "$" ) == 0 ) { /* pointer but don't free */
221  myPackItem->pointerType = NO_FREE_POINTER;
222  if ( gotTypeCast == 0 || gotItemName > 0 ) {
224  "parsePackInstruct: $ position error for %s", packInstruct );
225  if ( myPackItem != &packItemHead ) {
226  free( myPackItem );
227  }
229  }
230  continue;
231  }
232  else if ( gotTypeCast == 0 ) { /* a typeCast */
233  myPackItem->typeInx = ( packTypeInx_t )packTypeLookup( buf );
234  if ( myPackItem->typeInx < 0 ) {
236  "parsePackInstruct: packTypeLookup failed for %s in %s",
237  buf, packInstruct );
238  if ( myPackItem != &packItemHead ) {
239  free( myPackItem );
240  }
242  }
243  gotTypeCast = 1;
244  continue;
245  }
246  else if ( gotTypeCast == 1 && gotItemName == 0 ) { /* item name */
247  myPackItem->name = strdup( buf );
248  gotItemName = 1;
249  continue;
250  }
251  else {
253  "parsePackInstruct: too many string around %s in %s",
254  buf, packInstruct );
255  if ( myPackItem != &packItemHead ) {
256  free( myPackItem );
257  }
259  }
260  }
261  if ( myPackItem != NULL ) {
263  "parsePackInstruct: Pack Instruction %s not properly terminated",
264  packInstruct );
265  if ( myPackItem != &packItemHead ) {
266  free( myPackItem );
267  }
269  }
270  return 0;
271 }
272 
273 /* copy the next string from the inBuf to putBuf and advance the inBuf pointer.
274  * special char '*', ';' and '?' will be returned as a string.
275  */
276 int
277 copyStrFromPiBuf( const char *&inBuf, char *outBuf, int dependentFlag ) {
278  const char *inPtr = inBuf;
279  char *outPtr = outBuf;
280  int outLen = 0;
281  int c;
282 
283  while ( ( c = *inPtr ) != '\0' ) {
284  if ( dependentFlag > 0 ) {
285  /* read until ';' */
286  if ( c == ';' ) {
287  break;
288  }
289  else {
290  if ( outLen > 0 || !isspace( c ) ) {
291  *outPtr = c;
292  outPtr++;
293  outLen++;
294  }
295  inPtr++;
296  }
297  }
298  else if ( isspace( c ) ) {
299  inPtr++;
300  if ( outLen > 0 ) {
301  /* we got something */
302  break;
303  }
304  }
305  else if ( c == '*' || c == ';' || c == '?' || c == '$' ) {
306  if ( outLen > 0 ) {
307  /* what we have in outBuf is type cast. don't advance
308  * inPtr because we'll pick up next time
309  */
310  break;
311  }
312  else {
313  *outPtr = c;
314  outPtr++;
315  inPtr++;
316  outLen++;
317  break;
318  }
319  }
320  else { /* just a normal char */
321  *outPtr = c;
322  outPtr++;
323  inPtr++;
324  outLen++;
325  }
326  }
327 
328  *outPtr = '\0';
329  inBuf = inPtr;
330 
331  return outLen;
332 }
333 
334 int
335 packTypeLookup( const char *typeName ) {
336  /*TODO: i and return type should be reconsidered as of
337  packTypeInx_t */
338  for ( int i = 0; i < NumOfPackTypes; i++ ) {
339  if ( strcmp( typeName, packTypeTable[i].name ) == 0 ) {
340  return i;
341  }
342  }
343  return -1;
344 }
345 
347 initPackedOutput( const int len ) {
348  return {
349  .bBuf={
350  .buf=malloc(len),
351  .len=0
352  },
353  .bufSize=len,
354  .nopackBufArray={}
355  };
356 }
357 
359 initPackedOutputWithBuf( void *buf, const int len ) {
360  return {
361  .bBuf={
362  .buf=buf,
363  .len=0
364  },
365  .bufSize=len,
366  .nopackBufArray={}
367  };
368 }
369 
370 int
371 resolvePackedItem( packItem_t &myPackedItem, const void *&inPtr, packOpr_t packOpr ) {
372  int status;
373 
374  status = iparseDependent( myPackedItem );
375  if ( status < 0 ) {
376  return status;
377  }
378 
379  status = resolveDepInArray( myPackedItem );
380 
381  if ( status < 0 ) {
382  return status;
383  }
384 
385  /* set up the pointer */
386 
387  const void *ptr = inPtr;
388  if ( myPackedItem.pointerType > 0 ) {
389  if ( packOpr == PACK_OPR ) {
390  /* align the address */
391  ptr = ialignAddr( ptr );
392  if ( ptr != NULL ) {
393  myPackedItem.pointer = *static_cast<const void *const *>(ptr);
394  /* advance the pointer */
395  ptr = static_cast<const char *>(ptr) + sizeof(void *);
396  }
397  else {
398  myPackedItem.pointer = NULL;
399  }
400  }
401  }
402 
403  if ( strlen( myPackedItem.name ) == 0 ) {
404  if ( myPackedItem.pointerType == 0 || myPackedItem.pointer != NULL ) {
406  "resolvePackedItem: Cannot resolve %s",
407  myPackedItem.strValue );
409  }
410 
411  /* NULL pointer of unknown type: pack it as a string pointer */
412  free( myPackedItem.name );
413  myPackedItem.name = strdup( "STR_PTR_PI" );
414  }
415  inPtr = ptr;
416 
417  return 0;
418 }
419 
420 int
421 iparseDependent( packItem_t &myPackedItem ) {
422  int status;
423 
424  if ( myPackedItem.typeInx == PACK_DEPENDENT_TYPE ) {
425  status = resolveStrInItem( myPackedItem );
426  }
427  else if ( myPackedItem.typeInx == PACK_INT_DEPENDENT_TYPE ) {
428  status = resolveIntDepItem( myPackedItem );
429  }
430  else {
431  status = 0;
432  }
433  return status;
434 }
435 
436 int
437 resolveIntDepItem( packItem_t &myPackedItem ) {
438  char buf[MAX_NAME_LEN], myPI[MAX_NAME_LEN], *pfPtr = NULL;
439  int endReached = 0, c = 0;
440  int outLen = 0;
441  int keyVal = 0, status = 0;
442 
443  const char* tmpPtr = myPackedItem.name;
444  char* bufPtr = buf;
445 
446  /* get the key */
447 
448  while ( ( c = *tmpPtr ) != '\0' ) {
449  if ( c == ' ' || c == '\t' || c == '\n' || c == ':' ) {
450  /* white space */
451  if ( outLen == 0 ) {
452  tmpPtr ++;
453  continue;
454  }
455  else if ( endReached == 0 ) {
456  *bufPtr = '\0';
457  endReached = 1;
458  }
459  if ( c == ':' ) {
460  tmpPtr ++;
461  break;
462  }
463  }
464  else if ( c == ';' ) {
466  "resolveIntDepItem: end reached while parsing for key: %s",
467  myPackedItem.name );
469  }
470  else { /* just normal char */
471  *bufPtr = *tmpPtr;
472  outLen ++;
473  bufPtr ++;
474  }
475  tmpPtr++;
476  }
477 
478  keyVal = resolveIntInItem( buf, myPackedItem );
479  if ( keyVal == SYS_PACK_INSTRUCT_FORMAT_ERR ) {
481  "resolveIntDepItem: resolveIntInItem error for %s", buf );
483  }
484 
485  bufPtr = buf;
486 
487  while ( ( c = *tmpPtr ) != '\0' ) {
488  if ( c == ',' || c == '=' ) {
489  *bufPtr = '\0';
490  if ( strstr( buf, "default" ) != 0 || atoi( buf ) == keyVal ) {
491  /* get the PI */
492  if ( c == ',' ) {
493  /* skip to = */
494  while ( 1 ) {
495  c = *tmpPtr;
496  if ( c == '=' ) {
497  break;
498  }
499  else if ( c == ';' || c == ':' || c == '\0' ) {
501  "resolveIntDepItem: end reached with no PI%s",
502  myPackedItem.name );
504  }
505  tmpPtr++;
506  }
507  }
508  tmpPtr++;
509  myPI[0] = '\0';
510  pfPtr = myPI;
511  while ( 1 ) {
512  c = *tmpPtr;
513  if ( c == '\0' || c == ':' || c == ';' ) {
514  *pfPtr = ';';
515  pfPtr++;
516  *pfPtr = '\0';
517  break;
518  }
519  else {
520  *pfPtr = *tmpPtr;
521  tmpPtr ++;
522  pfPtr ++;
523  }
524  }
525  break;
526  }
527  bufPtr = buf; /* reset buffer */
528  if ( c == '=' ) {
529  tmpPtr++;
530  /* skip to next setting */
531  while ( 1 ) {
532  c = *tmpPtr;
533  if ( c == ':' ) {
534  break;
535  }
536  if ( c == '\0' || c == ';' ) {
538  "resolveIntDepItem: end reached with no PI%s",
539  myPackedItem.name );
541  }
542  tmpPtr++;
543  }
544  }
545  }
546  else { /* normal char */
547  *bufPtr = *tmpPtr;
548  bufPtr ++;
549  }
550  tmpPtr++;
551  }
552 
553  packItem_t newPackedItem{};
554  status = parsePackInstruct( myPI, newPackedItem );
555 
556  if ( status < 0 ) {
557  freePackedItem( newPackedItem );
559  "resolveIntDepItem: parsePackFormat error for =%s", myPI );
560  return status;
561  }
562 
563  /* reset the link and switch myPackedItem<->newPackedItem */
564  free( myPackedItem.name );
565 
566  packItem_t *lastPackedItem = &newPackedItem;
567  while (lastPackedItem->next) {
568  lastPackedItem = lastPackedItem->next;
569  }
570 
571  if ( newPackedItem.next ) {
572  newPackedItem.next->prev = &myPackedItem;
573  }
574  newPackedItem.prev = myPackedItem.prev;
575  lastPackedItem->next = myPackedItem.next;
576  if ( myPackedItem.next ) {
577  myPackedItem.next->prev = lastPackedItem;
578  }
579 
580  myPackedItem = newPackedItem;
581 
582  return 0;
583 }
584 
585 int
586 resolveIntInItem( const char *name, const packItem_t &myPackedItem ) {
587  int i;
588 
589  if ( isAllDigit( name ) ) {
590  return atoi( name );
591  }
592 
593  /* check the current item chain first */
594 
595  const packItem_t *tmpPackedItem = myPackedItem.prev;
596 
597  while ( tmpPackedItem != NULL ) {
598  if ( strcmp( name, tmpPackedItem->name ) == 0 &&
599  packTypeTable[tmpPackedItem->typeInx].number == PACK_INT_TYPE ) {
600  return tmpPackedItem->intValue;
601  }
602  if ( tmpPackedItem->prev == NULL && tmpPackedItem->parent != NULL ) {
603  tmpPackedItem = tmpPackedItem->parent;
604  }
605  else {
606  tmpPackedItem = tmpPackedItem->prev;
607  }
608  }
609 
610  /* Try the Rods Global table */
611 
612  i = 0;
613  while ( strcmp( PackConstantTable[i].name, PACK_TABLE_END_PI ) != 0 ) {
614  /* not the end */
615  if ( strcmp( PackConstantTable[i].name, name ) == 0 ) {
616  return PackConstantTable[i].value;
617  }
618  i++;
619  }
620 
622 }
623 
624 int
625 resolveStrInItem( packItem_t &myPackedItem ) {
626  const char *name = myPackedItem.strValue;
627  /* check the current item chain first */
628 
629  const packItem_t* tmpPackedItem = myPackedItem.prev;
630 
631  while ( tmpPackedItem != NULL ) {
632  if ( strcmp( name, tmpPackedItem->name ) == 0 &&
633  packTypeTable[tmpPackedItem->typeInx].number == PACK_PI_STR_TYPE ) {
634  break;
635  }
636  if ( tmpPackedItem->prev == NULL && tmpPackedItem->parent != NULL ) {
637  tmpPackedItem = tmpPackedItem->parent;
638  }
639  else {
640  tmpPackedItem = tmpPackedItem->prev;
641  }
642  }
643 
644  if ( tmpPackedItem == NULL ) {
646  "resolveStrInItem: Cannot resolve %s in %s",
647  name, myPackedItem.name );
649  }
650 
651  myPackedItem.typeInx = PACK_STRUCT_TYPE;
652  free( myPackedItem.name );
653  myPackedItem.name = strdup( tmpPackedItem->strValue );
654 
655  return 0;
656 }
657 
658 const char *
659 matchPackInstruct( const char *name, const packInstruct_t *myPackTable ) {
660 
661  if ( myPackTable != NULL ) {
662  for (int i = 0; strcmp( myPackTable[i].name, PACK_TABLE_END_PI ) != 0; ++i) {
663  if ( strcmp( myPackTable[i].name, name ) == 0 ) {
664  return myPackTable[i].packInstruct;
665  }
666  }
667  }
668 
669  /* Try the Rods Global table */
670 
671  for(int i = 0; strcmp( RodsPackTable[i].name, PACK_TABLE_END_PI ) != 0; ++i ) {
672  if ( strcmp( RodsPackTable[i].name, name ) == 0 ) {
673  return RodsPackTable[i].packInstruct;
674  }
675  }
676 
677  /* Try the API table */
680  if ( itr != pk_tbl.end() ) {
681  return itr->second.packInstruct.c_str();
682  }
683 
685  "matchPackInstruct: Cannot resolve %s",
686  name );
687 
688  return NULL;
689 }
690 
691 int
692 resolveDepInArray( packItem_t &myPackedItem ) {
693  myPackedItem.dim = myPackedItem.hintDim = 0;
694  char openSymbol = '\0'; // either '(', '[', or '\0' depending on whether we are
695  // in a parenthetical or bracketed expression, or not
696 
697  std::string buffer;
698  for ( size_t nameIndex = 0; '\0' != myPackedItem.name[ nameIndex ]; nameIndex++ ) {
699  char c = myPackedItem.name[ nameIndex ];
700  if ( '[' == c || '(' == c ) {
701  if ( openSymbol ) {
702  rodsLog( LOG_ERROR, "resolveDepInArray: got %c inside %c for %s",
703  c, openSymbol, myPackedItem.name );
705  }
706  else if ( ( '[' == c && myPackedItem.dim >= MAX_PACK_DIM ) ||
707  ( '(' == c && myPackedItem.hintDim >= MAX_PACK_DIM ) ) {
708  rodsLog( LOG_ERROR, "resolveDepInArray: dimension of %s larger than %d",
709  myPackedItem.name, MAX_PACK_DIM );
711  }
712  openSymbol = c;
713  myPackedItem.name[ nameIndex ] = '\0'; // isolate the name. may be used later
714  buffer.clear();
715  }
716  else if ( ']' == c || ')' == c ) {
717  if ( ( ']' == c && '[' != openSymbol ) ||
718  ( ')' == c && '(' != openSymbol ) ) {
719  rodsLog( LOG_ERROR, "resolveDepInArray: Got %c without %c for %s",
720  c, ( ']' == c ) ? '[' : '(', myPackedItem.name );
722  }
723  else if ( buffer.empty() ) {
724  rodsLog( LOG_ERROR, "resolveDepInArray: Empty %c%c in %s",
725  ( ']' == c ) ? '[' : '(', c, myPackedItem.name );
727  }
728  openSymbol = '\0';
729 
730  int& dimSize = ( ']' == c ) ?
731  myPackedItem.dimSize[myPackedItem.dim++] :
732  myPackedItem.hintDimSize[myPackedItem.hintDim++];
733  if ( ( dimSize = resolveIntInItem( buffer.c_str(), myPackedItem ) ) < 0 ) {
734  rodsLog( LOG_ERROR, "resolveDepInArray:resolveIntInItem error for %s, intName=%s",
735  myPackedItem.name, buffer.c_str() );
737  }
738  }
739  else if ( openSymbol ) {
740  buffer += c;
741  }
742  }
743  return 0;
744 }
745 
746 int
747 packNonpointerItem( packItem_t &myPackedItem, const void *&inPtr,
748  packedOutput_t &packedOutput, const packInstruct_t *myPackTable,
749  int packFlag, irodsProt_t irodsProt ) {
750  int i, status;
751 
752  int typeInx = myPackedItem.typeInx;
753  int numElement = getNumElement( myPackedItem );
754  int elementSz = packTypeTable[typeInx].size;
755  int myTypeNum = packTypeTable[typeInx].number;
756 
757  switch ( myTypeNum ) {
758  case PACK_CHAR_TYPE:
759  case PACK_BIN_TYPE:
760  /* no need to align inPtr */
761 
762  status = packChar( inPtr, packedOutput, numElement * elementSz,
763  myPackedItem.name, myPackedItem.typeInx, irodsProt );
764  if ( status < 0 ) {
765  return status;
766  }
767  break;
768  case PACK_STR_TYPE:
769  case PACK_PI_STR_TYPE: {
770  /* no need to align inPtr */
771  /* the size of the last dim is the max length of the string. Don't
772  * want to pack the entire length, just to end of the string including
773  * the NULL.
774  */
775  int maxStrLen, numStr, myDim;
776 
777  myDim = myPackedItem.dim;
778  if ( myDim <= 0 ) {
779  /* NULL pterminated */
780  maxStrLen = -1;
781  numStr = 1;
782  }
783  else {
784  maxStrLen = myPackedItem.dimSize[myDim - 1];
785  numStr = numElement / maxStrLen;
786  }
787 
788  /* save the str */
789  if ( numStr == 1 && myTypeNum == PACK_PI_STR_TYPE ) {
790  snprintf( myPackedItem.strValue, sizeof( myPackedItem.strValue ), "%s", static_cast<const char*>(inPtr) );
791  }
792 
793  for ( i = 0; i < numStr; i++ ) {
794  status = packString( inPtr, packedOutput, maxStrLen, myPackedItem.name,
795  irodsProt );
796  if ( status < 0 ) {
798  "packNonpointerItem:strlen %d of %s > dim size %d,content:%s",
799  strlen( ( const char* )inPtr ), myPackedItem.name, maxStrLen, inPtr );
800  return status;
801  }
802  }
803  break;
804  }
805  case PACK_INT_TYPE:
806  /* align inPtr to 4 bytes boundary. Will not align outPtr */
807 
808  inPtr = alignInt( inPtr );
809 
810  status = packInt( inPtr, packedOutput, numElement, myPackedItem.name,
811  irodsProt );
812  if ( status < 0 ) {
813  return status;
814  }
815  myPackedItem.intValue = status;
816  break;
817 
818  case PACK_INT16_TYPE:
819  /* align inPtr to 2 bytes boundary. Will not align outPtr */
820 
821  inPtr = alignInt16( inPtr );
822 
823  status = packInt16( inPtr, packedOutput, numElement, myPackedItem.name,
824  irodsProt );
825  if ( status < 0 ) {
826  return status;
827  }
828  myPackedItem.intValue = status;
829  break;
830 
831  case PACK_DOUBLE_TYPE:
832  /* align inPtr to 8 bytes boundary. Will not align outPtr */
833 #if defined(osx_platform)
834  /* osx does not align */
835  inPtr = alignInt( inPtr );
836 #else
837  inPtr = alignDouble( inPtr );
838 #endif
839 
840  status = packDouble( inPtr, packedOutput, numElement, myPackedItem.name,
841  irodsProt );
842  if ( status < 0 ) {
843  return status;
844  }
845  break;
846 
847  case PACK_STRUCT_TYPE:
848  /* no need to align boundary for struct */
849 
850  status = packChildStruct( inPtr, packedOutput, myPackedItem,
851  myPackTable, numElement, packFlag, irodsProt, NULL );
852 
853  if ( status < 0 ) {
854  return status;
855  }
856 
857  break;
858 
859  default:
861  "packNonpointerItem: Unknow type %d - %s ",
862  myTypeNum, myPackedItem.name );
864  }
865 
866  return 0;
867 }
868 
869 int
870 packPointerItem( packItem_t &myPackedItem, packedOutput_t &packedOutput,
871  const packInstruct_t *myPackTable, int packFlag, irodsProt_t irodsProt ) {
872  int i, j, status;
873  const void* singletonArray[1];
874  const void *pointer; /* working pointer */
875  const void *origPtr; /* for the purpose of freeing the original ptr */
876 
877  /* if it is a NULL pointer, just pack a NULL_PTR_PACK_STR string */
878  if ( myPackedItem.pointer == NULL ) {
879  if ( irodsProt == NATIVE_PROT ) {
880  packNullString( packedOutput );
881  }
882  return 0;
883  }
884 
885  int numElement = getNumHintElement( myPackedItem ); /* number of elements pointed to by one pointer */
886  int myDim = myPackedItem.dim;
887  int typeInx = myPackedItem.typeInx;
888  int numPointer = getNumElement( myPackedItem ); /* number of pointers in the array of pointer */
889  int elementSz = packTypeTable[typeInx].size;
890  int myTypeNum = packTypeTable[typeInx].number;
891 
892  /* pointer is already aligned */
893  const void *const * pointerArray = (myDim == 0) ? singletonArray : static_cast<const void *const*>(myPackedItem.pointer);
894  if ( myDim == 0 ) {
895  singletonArray[0] = myPackedItem.pointer;
896  if ( myTypeNum == PACK_PI_STR_TYPE ) {
897  /* save the str */
898  snprintf( myPackedItem.strValue, sizeof( myPackedItem.strValue ),
899  "%s", static_cast<const char*>(myPackedItem.pointer) );
900  }
901  }
902 
903  switch ( myTypeNum ) {
904  case PACK_CHAR_TYPE:
905  case PACK_BIN_TYPE:
906  for ( i = 0; i < numPointer; i++ ) {
907  origPtr = pointer = pointerArray[i];
908 
909  if ( myPackedItem.pointerType == NO_PACK_POINTER ) {
910  status = packNopackPointer( const_cast<void *>(pointer), packedOutput,
911  numElement * elementSz, myPackedItem.name, irodsProt );
912  }
913  else {
914  status = packChar( pointer, packedOutput,
915  numElement * elementSz, myPackedItem.name, myPackedItem.typeInx, irodsProt );
916  }
917  if ( ( packFlag & FREE_POINTER ) &&
918  myPackedItem.pointerType == A_POINTER ) {
919  free( const_cast<void*>(origPtr) );
920  }
921  if ( status < 0 ) {
922  return status;
923  }
924  }
925  if ( ( packFlag & FREE_POINTER ) &&
926  myPackedItem.pointerType == A_POINTER &&
927  numPointer > 0 && myDim > 0 ) {
928  /* Array of pointers */
929  free( const_cast<void**>(pointerArray) );
930  }
931  break;
932  case PACK_STR_TYPE:
933  case PACK_PI_STR_TYPE: {
934  /* the size of the last dim is the max length of the string. Don't
935  * want to pack the entire length, just to end of the string including
936  * the NULL.
937  */
938  int maxStrLen, numStr, myHintDim;
939  myHintDim = myPackedItem.hintDim;
940  if ( myHintDim <= 0 ) { /* just a pointer to a null terminated str */
941  maxStrLen = -1;
942  numStr = 1;
943  }
944  else {
945  /* the size of the last hint dimension */
946  maxStrLen = myPackedItem.hintDimSize[myHintDim - 1];
947  if ( numElement <= 0 || maxStrLen <= 0 ) {
948  return 0;
949  }
950  numStr = numElement / maxStrLen;
951  }
952 
953  for ( j = 0; j < numPointer; j++ ) {
954  origPtr = pointer = pointerArray[j];
955 
956  for ( i = 0; i < numStr; i++ ) {
957  status = packString( pointer, packedOutput, maxStrLen,
958  myPackedItem.name, irodsProt );
959  if ( status < 0 ) {
961  "packPointerItem: strlen of %s > dim size, content: %s ",
962  myPackedItem.name, pointer );
963  return status;
964  }
965  }
966  if ( ( packFlag & FREE_POINTER ) &&
967  myPackedItem.pointerType == A_POINTER ) {
968  free( const_cast<void*>(origPtr) );
969  }
970  }
971  if ( ( packFlag & FREE_POINTER ) &&
972  myPackedItem.pointerType == A_POINTER &&
973  numPointer > 0 && myDim > 0 ) {
974  /* Array of pointers */
975  free( const_cast<void**>(pointerArray) );
976  }
977  break;
978  }
979  case PACK_INT_TYPE:
980  for ( i = 0; i < numPointer; i++ ) {
981  origPtr = pointer = pointerArray[i];
982 
983  status = packInt( pointer, packedOutput, numElement,
984  myPackedItem.name, irodsProt );
985  if ( ( packFlag & FREE_POINTER ) &&
986  myPackedItem.pointerType == A_POINTER ) {
987  free( const_cast<void*>(origPtr) );
988  }
989  if ( status < 0 ) {
990  return status;
991  }
992  }
993 
994  if ( ( packFlag & FREE_POINTER ) &&
995  myPackedItem.pointerType == A_POINTER &&
996  numPointer > 0 && myDim > 0 ) {
997  /* Array of pointers */
998  free( const_cast<void**>(pointerArray) );
999  }
1000  break;
1001 
1002  case PACK_INT16_TYPE:
1003  for ( i = 0; i < numPointer; i++ ) {
1004  origPtr = pointer = pointerArray[i];
1005 
1006  status = packInt16( pointer, packedOutput, numElement,
1007  myPackedItem.name, irodsProt );
1008  if ( ( packFlag & FREE_POINTER ) &&
1009  myPackedItem.pointerType == A_POINTER ) {
1010  free( const_cast<void*>(origPtr) );
1011  }
1012  if ( status < 0 ) {
1013  return status;
1014  }
1015  }
1016 
1017  if ( ( packFlag & FREE_POINTER ) &&
1018  myPackedItem.pointerType == A_POINTER &&
1019  numPointer > 0 && myDim > 0 ) {
1020  /* Array of pointers */
1021  free( const_cast<void**>(pointerArray) );
1022  }
1023  break;
1024 
1025  case PACK_DOUBLE_TYPE:
1026  for ( i = 0; i < numPointer; i++ ) {
1027  origPtr = pointer = pointerArray[i];
1028 
1029  status = packDouble( pointer, packedOutput, numElement,
1030  myPackedItem.name, irodsProt );
1031  if ( ( packFlag & FREE_POINTER ) &&
1032  myPackedItem.pointerType == A_POINTER ) {
1033  free( const_cast<void*>(origPtr) );
1034  }
1035  if ( status < 0 ) {
1036  return status;
1037  }
1038  }
1039 
1040  if ( ( packFlag & FREE_POINTER ) &&
1041  myPackedItem.pointerType == A_POINTER &&
1042  numPointer > 0 && myDim > 0 ) {
1043  /* Array of pointers */
1044  free( const_cast<void**>(pointerArray) );
1045  }
1046  break;
1047 
1048  case PACK_STRUCT_TYPE:
1049  /* no need to align boundary for struct */
1050 
1051  for ( i = 0; i < numPointer; i++ ) {
1052  origPtr = pointer = pointerArray[i];
1053  status = packChildStruct( pointer, packedOutput, myPackedItem,
1054  myPackTable, numElement, packFlag, irodsProt, NULL );
1055  if ( ( packFlag & FREE_POINTER ) &&
1056  myPackedItem.pointerType == A_POINTER ) {
1057  free( const_cast<void*>(origPtr) );
1058  }
1059  if ( status < 0 ) {
1060  return status;
1061  }
1062  }
1063  if ( ( packFlag & FREE_POINTER ) &&
1064  myPackedItem.pointerType == A_POINTER
1065  && numPointer > 0 && myDim > 0 ) {
1066  /* Array of pointers */
1067  free( const_cast<void**>(pointerArray) );
1068  }
1069  break;
1070 
1071  default:
1072  rodsLog( LOG_ERROR,
1073  "packNonpointerItem: Unknown type %d - %s ",
1074  myTypeNum, myPackedItem.name );
1076  }
1077  return 0;
1078 }
1079 
1080 int
1081 getNumElement( const packItem_t &myPackedItem ) {
1082  int numElement = 1;
1083  for ( int i = 0; i < myPackedItem.dim; i++ ) {
1084  numElement *= myPackedItem.dimSize[i];
1085  }
1086  return numElement;
1087 }
1088 
1089 int
1090 getNumHintElement( const packItem_t &myPackedItem ) {
1091  int numElement = 1;
1092  for ( int i = 0; i < myPackedItem.hintDim; i++ ) {
1093  numElement *= myPackedItem.hintDimSize[i];
1094  }
1095  return numElement;
1096 }
1097 
1098 int
1099 extendPackedOutput( packedOutput_t &packedOutput, int extLen, void *&outPtr ) {
1100 
1101  int newOutLen = packedOutput.bBuf.len + extLen;
1102  if ( newOutLen <= packedOutput.bufSize ) {
1103  outPtr = ( char * ) packedOutput.bBuf.buf + packedOutput.bBuf.len;
1104  return 0;
1105  }
1106 
1107  /* double the size */
1108  int newBufSize = packedOutput.bufSize + packedOutput.bufSize;
1109  if ( newBufSize <= newOutLen ||
1110  packedOutput.bufSize > MAX_PACKED_OUT_ALLOC_SZ ) {
1111  newBufSize = newOutLen + PACKED_OUT_ALLOC_SZ;
1112  }
1113 
1114  packedOutput.bBuf.buf = realloc( packedOutput.bBuf.buf, newBufSize );
1115  packedOutput.bufSize = newBufSize;
1116 
1117  if ( packedOutput.bBuf.buf == NULL ) {
1118  rodsLog( LOG_ERROR,
1119  "extendPackedOutput: error malloc of size %d", newBufSize );
1120  outPtr = NULL;
1121  return SYS_MALLOC_ERR;
1122  }
1123  outPtr = static_cast<char*>(packedOutput.bBuf.buf) + packedOutput.bBuf.len;
1124 
1125  /* set the remaining to 0 */
1126  memset( outPtr, 0, newBufSize - packedOutput.bBuf.len );
1127 
1128  return 0;
1129 }
1130 
1131 int
1132 packItem( packItem_t &myPackedItem, const void *&inPtr, packedOutput_t &packedOutput,
1133  const packInstruct_t *myPackTable, int packFlag, irodsProt_t irodsProt ) {
1134  int status;
1135 
1136  status = resolvePackedItem( myPackedItem, inPtr, PACK_OPR );
1137  if ( status < 0 ) {
1138  return status;
1139  }
1140  if ( myPackedItem.pointerType > 0 ) {
1141  /* a pointer type */
1142  status = packPointerItem( myPackedItem, packedOutput,
1143  myPackTable, packFlag, irodsProt );
1144  }
1145  else {
1146  status = packNonpointerItem( myPackedItem, inPtr, packedOutput,
1147  myPackTable, packFlag, irodsProt );
1148  }
1149 
1150  return status;
1151 }
1152 
1153 int
1154 packChar( const void *&inPtr, packedOutput_t &packedOutput, int len,
1155  const char* name, const packTypeInx_t typeInx, irodsProt_t irodsProt ) {
1156 
1157  if ( len <= 0 ) {
1158  return 0;
1159  }
1160 
1161  if ( irodsProt == XML_PROT ) {
1162  packXmlTag( name, packedOutput, START_TAG_FL );
1163  }
1164 
1165  if ( irodsProt == XML_PROT &&
1166  packTypeTable[typeInx].number == PACK_BIN_TYPE ) {
1167  /* a bin pack type. encode it */
1168  unsigned long outlen;
1169  int status;
1170 
1171  outlen = 2 * len + 10;
1172  void *outPtr;
1173  extendPackedOutput( packedOutput, outlen, outPtr );
1174  if ( inPtr == NULL ) { /* A NULL pointer */
1175  /* Don't think we'll have this condition. just fill it with 0 */
1176  memset( outPtr, 0, len );
1177  packedOutput.bBuf.len += len;
1178  }
1179  else {
1180  status = base64_encode( static_cast<const unsigned char *>(inPtr), len,
1181  static_cast<unsigned char *>(outPtr), &outlen );
1182  if ( status < 0 ) {
1183  return status;
1184  }
1185  inPtr = static_cast<const char*>(inPtr) + len;
1186  packedOutput.bBuf.len += outlen;
1187  }
1188  }
1189  else {
1190  void *outPtr;
1191  extendPackedOutput( packedOutput, len, outPtr );
1192  if ( inPtr == NULL ) { /* A NULL pointer */
1193  /* Don't think we'll have this condition. just fill it with 0 */
1194  memset( outPtr, 0, len );
1195  }
1196  else {
1197  memcpy( outPtr, inPtr, len );
1198  inPtr = static_cast<const char *>(inPtr) + len;
1199  }
1200  packedOutput.bBuf.len += len;
1201  }
1202 
1203  if ( irodsProt == XML_PROT ) {
1204  packXmlTag( name, packedOutput, END_TAG_FL );
1205  }
1206 
1207  return 0;
1208 }
1209 
1210 int
1211 packString( const void *&inPtr, packedOutput_t &packedOutput, int maxStrLen,
1212  const char* name, irodsProt_t irodsProt ) {
1213  int status;
1214 
1215  if ( irodsProt == XML_PROT ) {
1216  status = packXmlString( inPtr, packedOutput, maxStrLen, name );
1217  }
1218  else {
1219  status = packNatString( inPtr, packedOutput, maxStrLen );
1220  }
1221 
1222  return status;
1223 }
1224 
1225 int
1226 packNatString( const void *&inPtr, packedOutput_t &packedOutput, int maxStrLen ) {
1227  int myStrlen;
1228 
1229  if ( inPtr == NULL ) {
1230  myStrlen = 0;
1231  }
1232  else {
1233  myStrlen = strlen( ( const char* )inPtr );
1234  }
1235  if ( maxStrLen >= 0 && myStrlen >= maxStrLen ) {
1237  }
1238 
1239  void *outPtr;
1240  int status = extendPackedOutput( packedOutput, myStrlen + 1, outPtr );
1241  if ( SYS_MALLOC_ERR == status ) {
1242  return status;
1243  }
1244 
1245  if ( myStrlen == 0 ) {
1246  memset( outPtr, 0, 1 );
1247  }
1248  else {
1249  strncpy( static_cast<char*>(outPtr), static_cast<const char*>(inPtr), myStrlen + 1 );
1250  }
1251 
1252  if ( maxStrLen > 0 ) {
1253  inPtr = ( const char * )inPtr + maxStrLen;
1254  }
1255  else {
1256  inPtr = ( const char * )inPtr + myStrlen + 1;
1257  }
1258 
1259  packedOutput.bBuf.len += ( myStrlen + 1 );
1260 
1261  return 0;
1262 }
1263 
1264 int
1265 packXmlString( const void *&inPtr, packedOutput_t &packedOutput, int maxStrLen,
1266  const char* name ) {
1267 
1268  if ( !inPtr ) {
1269  rodsLog( LOG_ERROR, "packXmlString :: null inPtr" );
1271  }
1272 
1273  int myStrlen = strlen( static_cast<const char*>(inPtr) );
1274  char *xmlStr = nullptr;
1275  int xmlLen = strToXmlStr( static_cast<const char*>(inPtr), xmlStr );
1276  if ( NULL == xmlStr ) { // JMC cppcheck - nullptr
1277  rodsLog( LOG_ERROR, "packXmlString :: null xmlStr" );
1278  return -1;
1279  }
1280 
1281  if ( maxStrLen >= 0 && myStrlen >= maxStrLen ) {
1282  free( xmlStr );
1284  }
1285  packXmlTag( name, packedOutput, START_TAG_FL );
1286 
1287  void *outPtr;
1288  int status = extendPackedOutput( packedOutput, xmlLen + 1, outPtr );
1289  if ( SYS_MALLOC_ERR == status ) {
1290  free( xmlStr );
1291  return status;
1292  }
1293 
1294  if ( xmlLen == 0 ) {
1295  memset( outPtr, 0, 1 );
1296  }
1297  else {
1298  strncpy( static_cast<char*>(outPtr), xmlStr, xmlLen + 1 );
1299  }
1300 
1301  if ( maxStrLen > 0 ) {
1302  inPtr = ( const char * )inPtr + maxStrLen;
1303  }
1304  else {
1305  inPtr = ( const char * )inPtr + xmlLen + 1;
1306  }
1307 
1308  packedOutput.bBuf.len += ( xmlLen );
1309  packXmlTag( name, packedOutput, END_TAG_FL );
1310  free( xmlStr );
1311  return 0;
1312 }
1313 
1314 int
1315 strToXmlStr( const char *inStr, char *&outXmlStr ) {
1316  outXmlStr = NULL;
1317  if ( inStr == NULL ) {
1318  return 0;
1319  }
1320 
1321  std::size_t copy_from = 0;
1322  std::stringstream xml{};
1323  std::size_t i;
1324  for ( i = 0; inStr[i] != '\0'; ++i ) {
1325  switch(inStr[i]) {
1326  case '&':
1327  xml.write(inStr + copy_from, i - copy_from);
1328  copy_from = i + 1;
1329  xml << "&amp;";
1330  break;
1331  case '<':
1332  xml.write(inStr + copy_from, i - copy_from);
1333  copy_from = i + 1;
1334  xml << "&lt;";
1335  break;
1336  case '>':
1337  xml.write(inStr + copy_from, i - copy_from);
1338  copy_from = i + 1;
1339  xml << "&gt;";
1340  break;
1341  case '"':
1342  xml.write(inStr + copy_from, i - copy_from);
1343  copy_from = i + 1;
1344  xml << "&quot;";
1345  break;
1346  case '`':
1347  xml.write(inStr + copy_from, i - copy_from);
1348  copy_from = i + 1;
1349  xml << "&apos;";
1350  break;
1351  }
1352  }
1353  xml.write(inStr + copy_from, i - copy_from);
1354  outXmlStr = strdup(xml.str().c_str());
1355 
1356  return strlen( outXmlStr );
1357 
1358 }
1359 
1360 int
1361 xmlStrToStr( const char *inStr, int len, char *&outStr ) {
1362  outStr = nullptr;
1363  if ( inStr == NULL || len <= 0 ) {
1364  return 0;
1365  }
1366 
1367  std::size_t copy_from = 0;
1368  std::stringstream s{};
1369  for (std::size_t i = 0; i < static_cast<std::size_t>(len); ++i ) {
1370  if (inStr[i] == '&') {
1371  s.write(inStr + copy_from, i - copy_from);
1372  if ( strncmp( inStr + i + 1, "amp;", 4 ) == 0 ) {
1373  s << '&';
1374  i += 4;
1375  } else if ( strncmp( inStr + i + 1, "lt;", 3 ) == 0 ) {
1376  s << '<';
1377  i += 3;
1378  } else if ( strncmp( inStr + i + 1, "gt;", 3 ) == 0 ) {
1379  s << '>';
1380  i += 3;
1381  } else if ( strncmp( inStr + i + 1, "quot;", 5 ) == 0 ) {
1382  s << '"';
1383  i += 5;
1384  } else if ( strncmp( inStr + i + 1, "apos;", 5 ) == 0 ) {
1385  s << '`';
1386  i += 5;
1387  } else {
1388  break;
1389  }
1390  copy_from = i + 1;
1391  }
1392  }
1393  s.write(inStr + copy_from, len - copy_from);
1394  outStr = strdup(s.str().c_str());
1395 
1396  return strlen( outStr );
1397 }
1398 
1399 int
1400 packNullString( packedOutput_t &packedOutput ) {
1401 
1402  int myStrlen = strlen( NULL_PTR_PACK_STR );
1403  void *outPtr;
1404  int status = extendPackedOutput( packedOutput, myStrlen + 1, outPtr );
1405  if ( SYS_MALLOC_ERR == status ) {
1406  return status;
1407  }
1408  strncpy( static_cast<char*>(outPtr), NULL_PTR_PACK_STR, myStrlen + 1 );
1409  packedOutput.bBuf.len += ( myStrlen + 1 );
1410  return 0;
1411 }
1412 
1413 int
1414 packInt( const void *&inPtr, packedOutput_t &packedOutput, int numElement,
1415  const char* name, irodsProt_t irodsProt ) {
1416 
1417  if ( numElement == 0 ) {
1418  return 0;
1419  }
1420 
1421  int intValue = 0;
1422 
1423  if ( irodsProt == XML_PROT ) {
1424  if ( inPtr == NULL ) {
1425  /* pack nothing */
1426  return 0;
1427  }
1428  const int* inIntPtr = ( const int * )inPtr;
1429  intValue = *inIntPtr;
1430  for ( int i = 0; i < numElement; i++ ) {
1431  packXmlTag( name, packedOutput, START_TAG_FL );
1432  void *outPtr;
1433  extendPackedOutput( packedOutput, 12, outPtr );
1434  snprintf( static_cast<char*>(outPtr), 12, "%d", *inIntPtr );
1435  packedOutput.bBuf.len += ( strlen( static_cast<char*>(outPtr) ) );
1436  packXmlTag( name, packedOutput, END_TAG_FL );
1437  inIntPtr++;
1438  }
1439  inPtr = inIntPtr;
1440  }
1441  else {
1442  int* origIntPtr = ( int * ) malloc( sizeof( int ) * numElement );
1443 
1444  if ( inPtr == NULL ) {
1445  /* a NULL pointer, fill the array with 0 */
1446  memset( origIntPtr, 0, sizeof( int ) * numElement );
1447  }
1448  else {
1449  const int* inIntPtr = ( const int * )inPtr;
1450  intValue = *inIntPtr;
1451  int* tmpIntPtr = origIntPtr;
1452  for ( int i = 0; i < numElement; i++ ) {
1453  *tmpIntPtr = htonl( *inIntPtr );
1454  tmpIntPtr ++;
1455  inIntPtr ++;
1456  }
1457  inPtr = inIntPtr;
1458  }
1459 
1460  void *outPtr;
1461 
1462  extendPackedOutput( packedOutput, sizeof( int ) * numElement, outPtr );
1463  memcpy( outPtr, origIntPtr, sizeof( int ) * numElement );
1464  free( origIntPtr );
1465  packedOutput.bBuf.len += ( sizeof( int ) * numElement );
1466 
1467  }
1468  if ( intValue < 0 ) {
1469  /* prevent error exiting */
1470  intValue = 0;
1471  }
1472 
1473  return intValue;
1474 }
1475 
1476 int
1477 packInt16( const void *&inPtr, packedOutput_t &packedOutput, int numElement,
1478  const char* name, irodsProt_t irodsProt ) {
1479  short *tmpIntPtr, *origIntPtr;
1480  int i;
1481  void *outPtr;
1482  short intValue = 0;
1483 
1484  if ( numElement == 0 ) {
1485  return 0;
1486  }
1487 
1488  const short* inIntPtr = ( const short * )inPtr;
1489 
1490  if ( inIntPtr != NULL ) {
1491  /* save this and return later */
1492  intValue = *inIntPtr;
1493  }
1494 
1495  if ( irodsProt == XML_PROT ) {
1496  if ( inIntPtr == NULL ) {
1497  /* pack nothing */
1498  return 0;
1499  }
1500  for ( i = 0; i < numElement; i++ ) {
1501  packXmlTag( name, packedOutput, START_TAG_FL );
1502  extendPackedOutput( packedOutput, 12, outPtr );
1503  snprintf( static_cast<char*>(outPtr), 12, "%hi", *inIntPtr );
1504  packedOutput.bBuf.len += ( strlen( static_cast<char*>(outPtr) ) );
1505  packXmlTag( name, packedOutput, END_TAG_FL );
1506  inIntPtr++;
1507  }
1508  inPtr = inIntPtr;
1509  }
1510  else {
1511  origIntPtr = tmpIntPtr = ( short * ) malloc( sizeof( short ) * numElement );
1512 
1513  if ( inIntPtr == NULL ) {
1514  /* a NULL pointer, fill the array with 0 */
1515  memset( origIntPtr, 0, sizeof( short ) * numElement );
1516  }
1517  else {
1518  for ( i = 0; i < numElement; i++ ) {
1519  *tmpIntPtr = htons( *inIntPtr );
1520  tmpIntPtr ++;
1521  inIntPtr ++;
1522  }
1523  inPtr = inIntPtr;
1524  }
1525 
1526  extendPackedOutput( packedOutput, sizeof( short ) * numElement, outPtr );
1527  memcpy( outPtr, origIntPtr, sizeof( short ) * numElement );
1528  free( origIntPtr );
1529  packedOutput.bBuf.len += ( sizeof( short ) * numElement );
1530 
1531  }
1532  if ( intValue < 0 ) {
1533  /* prevent error exiting */
1534  intValue = 0;
1535  }
1536 
1537  return intValue;
1538 }
1539 
1540 int
1541 packDouble( const void *&inPtr, packedOutput_t &packedOutput, int numElement,
1542  const char* name, irodsProt_t irodsProt ) {
1543  rodsLong_t *tmpDoublePtr, *origDoublePtr;
1544  int i;
1545  void *outPtr;
1546 
1547  if ( numElement == 0 ) {
1548  return 0;
1549  }
1550 
1551  const rodsLong_t* inDoublePtr = ( const rodsLong_t * )inPtr;
1552 
1553  if ( irodsProt == XML_PROT ) {
1554  if ( inDoublePtr == NULL ) {
1555  /* pack nothing */
1556  return 0;
1557  }
1558  for ( i = 0; i < numElement; i++ ) {
1559  packXmlTag( name, packedOutput, START_TAG_FL );
1560  extendPackedOutput( packedOutput, 20, outPtr );
1561  snprintf( static_cast<char*>(outPtr), 20, "%lld", *inDoublePtr );
1562  packedOutput.bBuf.len += ( strlen( static_cast<char*>(outPtr) ) );
1563  packXmlTag( name, packedOutput, END_TAG_FL );
1564  inDoublePtr++;
1565  }
1566  inPtr = inDoublePtr;
1567  }
1568  else {
1569  origDoublePtr = tmpDoublePtr = ( rodsLong_t * ) malloc(
1570  sizeof( rodsLong_t ) * numElement );
1571 
1572  if ( inDoublePtr == NULL ) {
1573  /* a NULL pointer, fill the array with 0 */
1574  memset( origDoublePtr, 0, sizeof( rodsLong_t ) * numElement );
1575  }
1576  else {
1577  for ( i = 0; i < numElement; i++ ) {
1578  myHtonll( *inDoublePtr, tmpDoublePtr );
1579  tmpDoublePtr ++;
1580  inDoublePtr ++;
1581  }
1582  inPtr = inDoublePtr;
1583  }
1584  extendPackedOutput( packedOutput, sizeof( rodsLong_t ) * numElement,
1585  outPtr );
1586  memcpy( outPtr, origDoublePtr, sizeof( rodsLong_t ) * numElement );
1587  free( origDoublePtr );
1588  packedOutput.bBuf.len += ( sizeof( rodsLong_t ) * numElement );
1589  }
1590 
1591  return 0;
1592 }
1593 
1594 int
1595 packChildStruct( const void *&inPtr, packedOutput_t &packedOutput,
1596  const packItem_t &myPackedItem, const packInstruct_t *myPackTable, int numElement,
1597  int packFlag, irodsProt_t irodsProt, const char *packInstructInp ) {
1598 
1599  if ( numElement == 0 ) {
1600  return 0;
1601  }
1602 
1603  if ( packInstructInp == NULL ) {
1604  packInstructInp = matchPackInstruct( myPackedItem.name, myPackTable );
1605  }
1606 
1607  if ( packInstructInp == NULL ) {
1608  rodsLog( LOG_ERROR,
1609  "packChildStruct: matchPackInstruct failed for %s",
1610  myPackedItem.name );
1611  return SYS_UNMATCH_PACK_INSTRUCTI_NAME;
1612  }
1613 
1614  for ( int i = 0; i < numElement; i++ ) {
1615  packItem_t packItemHead{};
1616 
1617  int status = parsePackInstruct(packInstructInp, packItemHead );
1618  if ( status < 0 ) {
1619  freePackedItem( packItemHead );
1620  return status;
1621  }
1622  /* link it */
1623  packItemHead.parent = &myPackedItem;
1624 
1625  if ( irodsProt == XML_PROT ) {
1626  packXmlTag( myPackedItem.name, packedOutput, START_TAG_FL | LF_FL );
1627  }
1628 
1629  /* now pack each child item */
1630  packItem_t* tmpItem = &packItemHead;
1631  while ( tmpItem != NULL ) {
1632 #if defined(solaris_platform)
1633  if ( tmpItem->pointerType == 0 &&
1634  packTypeTable[tmpItem->typeInx].number == PACK_DOUBLE_TYPE ) {
1635  doubleInStruct = 1;
1636  }
1637 #endif
1638  int status = packItem( *tmpItem, inPtr, packedOutput,
1639  myPackTable, packFlag, irodsProt );
1640  if ( status < 0 ) {
1641  return status;
1642  }
1643  tmpItem = tmpItem->next;
1644  }
1645  freePackedItem( packItemHead );
1646 #if defined(solaris_platform)
1647  /* seems that solaris align to 64 bit boundary if there is any
1648  * double in struct */
1649  if ( doubleInStruct > 0 ) {
1650  inPtr = alignDouble( inPtr );
1651  }
1652 #endif
1653  if ( irodsProt == XML_PROT ) {
1654  packXmlTag( myPackedItem.name, packedOutput, END_TAG_FL );
1655  }
1656  }
1657  return 0;
1658 }
1659 
1660 int
1661 freePackedItem( packItem_t &packItemHead ) {
1662  free( packItemHead.name );
1663  packItem_t *tmpItem = packItemHead.next;
1664  while ( tmpItem ) {
1665  packItem_t* nextItem = tmpItem->next;
1666  free( tmpItem->name );
1667  free( tmpItem );
1668  tmpItem = nextItem;
1669  }
1670 
1671  return 0;
1672 }
1673 
1674 int
1675 unpackItem( packItem_t &myPackedItem, const void *&inPtr,
1676  packedOutput_t &unpackedOutput, const packInstruct_t *myPackTable,
1677  irodsProt_t irodsProt ) {
1678  int status;
1679 
1680  status = resolvePackedItem( myPackedItem, inPtr, UNPACK_OPR );
1681  if ( status < 0 ) {
1682  return status;
1683  }
1684  if ( myPackedItem.pointerType > 0 ) {
1685  /* a pointer type */
1686  status = unpackPointerItem( myPackedItem, inPtr, unpackedOutput,
1687  myPackTable, irodsProt );
1688  }
1689  else {
1690  status = unpackNonpointerItem( myPackedItem, inPtr, unpackedOutput,
1691  myPackTable, irodsProt );
1692  }
1693 
1694  return status;
1695 }
1696 
1697 int
1698 unpackNonpointerItem( packItem_t &myPackedItem, const void *&inPtr,
1699  packedOutput_t &unpackedOutput, const packInstruct_t *myPackTable,
1700  irodsProt_t irodsProt ) {
1701  int i, status = 0;
1702 
1703  int typeInx = myPackedItem.typeInx;
1704  int numElement = getNumElement( myPackedItem );
1705  int elementSz = packTypeTable[typeInx].size;
1706  int myTypeNum = packTypeTable[typeInx].number;
1707 
1708  switch ( myTypeNum ) {
1709  case PACK_CHAR_TYPE:
1710  case PACK_BIN_TYPE:
1711  status = unpackChar( inPtr, unpackedOutput, numElement * elementSz,
1712  myPackedItem.name, myPackedItem.typeInx, irodsProt );
1713  if ( status < 0 ) {
1714  return status;
1715  }
1716  break;
1717  case PACK_STR_TYPE:
1718  case PACK_PI_STR_TYPE: {
1719  /* no need to align inPtr */
1720  /* the size of the last dim is the max length of the string. Don't
1721  * want to pack the entire length, just to end of the string including
1722  * the NULL.
1723  */
1724  int maxStrLen, numStr, myDim;
1725 
1726  myDim = myPackedItem.dim;
1727  if ( myDim <= 0 ) {
1728  /* null terminated */
1729  maxStrLen = -1;
1730  numStr = 1;
1731  }
1732  else {
1733  maxStrLen = myPackedItem.dimSize[myDim - 1];
1734  numStr = numElement / maxStrLen;
1735  }
1736 
1737  for ( i = 0; i < numStr; i++ ) {
1738  char *outStr = NULL;
1739  status = unpackString( inPtr, unpackedOutput, maxStrLen,
1740  myPackedItem.name, irodsProt, outStr );
1741  if ( status < 0 ) {
1742  rodsLog( LOG_ERROR,
1743  "unpackNonpointerItem: strlen of %s > dim size, content: %s ",
1744  myPackedItem.name, inPtr );
1745  return status;
1746  }
1747  if ( myTypeNum == PACK_PI_STR_TYPE && i == 0 && outStr != NULL ) {
1748  strncpy( myPackedItem.strValue, outStr, NAME_LEN );
1749  }
1750  }
1751  break;
1752  }
1753  case PACK_INT_TYPE:
1754  status = unpackInt( inPtr, unpackedOutput, numElement,
1755  myPackedItem.name, irodsProt );
1756  if ( status < 0 ) {
1757  return status;
1758  }
1759  myPackedItem.intValue = status;
1760  break;
1761  case PACK_INT16_TYPE:
1762  status = unpackInt16( inPtr, unpackedOutput, numElement,
1763  myPackedItem.name, irodsProt );
1764  if ( status < 0 ) {
1765  return status;
1766  }
1767  myPackedItem.intValue = status;
1768  break;
1769  case PACK_DOUBLE_TYPE:
1770  status = unpackDouble( inPtr, unpackedOutput, numElement,
1771  myPackedItem.name, irodsProt );
1772  if ( status < 0 ) {
1773  return status;
1774  }
1775  break;
1776  case PACK_STRUCT_TYPE:
1777  status = unpackChildStruct( inPtr, unpackedOutput, myPackedItem,
1778  myPackTable, numElement, irodsProt, NULL );
1779 
1780  if ( status < 0 ) {
1781  return status;
1782  }
1783  break;
1784  default:
1785  rodsLog( LOG_ERROR,
1786  "unpackNonpointerItem: Unknow type %d - %s ",
1787  myTypeNum, myPackedItem.name );
1788  return SYS_PACK_INSTRUCT_FORMAT_ERR;
1789  }
1790  return status;
1791 }
1792 /* unpackChar - This routine functionally is the same as packChar */
1793 
1794 int
1795 unpackChar( const void *&inPtr, packedOutput_t &unpackedOutput, int len,
1796  const char* name, const packTypeInx_t typeInx, irodsProt_t irodsProt ) {
1797  void *outPtr;
1798 
1799  if ( len <= 0 ) {
1800  return 0;
1801  }
1802 
1803  /* no need to align address */
1804 
1805  extendPackedOutput( unpackedOutput, len, outPtr );
1806  if ( inPtr == NULL ) { /* A NULL pointer */
1807  /* just fill it with 0 */
1808  memset( outPtr, 0, len );
1809  }
1810  else {
1811  unpackCharToOutPtr( inPtr, outPtr, len, name, typeInx, irodsProt );
1812  }
1813  unpackedOutput.bBuf.len += len;
1814 
1815  return 0;
1816 }
1817 
1818 int
1819 unpackCharToOutPtr( const void *&inPtr, void *&outPtr, int len,
1820  const char* name, const packTypeInx_t typeInx, irodsProt_t irodsProt ) {
1821  int status;
1822 
1823  if ( irodsProt == XML_PROT ) {
1824  status = unpackXmlCharToOutPtr( inPtr, outPtr, len, name, typeInx );
1825  }
1826  else {
1827  status = unpackNatCharToOutPtr( inPtr, outPtr, len );
1828  }
1829  return status;
1830 }
1831 
1832 int
1833 unpackNatCharToOutPtr( const void *&inPtr, void *&outPtr, int len ) {
1834  memcpy( outPtr, inPtr, len );
1835  inPtr = static_cast<const char*>(inPtr) + len;
1836  outPtr = static_cast<char*>(outPtr) + len;
1837 
1838  return 0;
1839 }
1840 
1841 int
1842 unpackXmlCharToOutPtr( const void *&inPtr, void *&outPtr, int len,
1843  const char* name, const packTypeInx_t typeInx ) {
1844  int endTagLen = 0;
1845  int inLen = parseXmlValue( inPtr, name, endTagLen );
1846  if ( inLen < 0 ) {
1847  return inLen;
1848  }
1849 
1850  if ( packTypeTable[typeInx].number == PACK_BIN_TYPE ) {
1851  /* bin type. need to decode */
1852  unsigned long outLen = len;
1853  if ( int status = base64_decode( static_cast<const unsigned char *>(inPtr), inLen,
1854  static_cast<unsigned char *>(outPtr), &outLen ) ) {
1855  return status;
1856  }
1857  if ( static_cast<int>(outLen) != len ) {
1858  rodsLog( LOG_NOTICE,
1859  "unpackXmlCharToOutPtr: required len %d != %d from base64_decode",
1860  len, outLen );
1861  }
1862  }
1863  else {
1864  if ( inLen != len ) {
1865  rodsLog( LOG_NOTICE,
1866  "unpackXmlCharToOutPtr: required len %d != %d from input",
1867  len, inLen );
1868  if ( inLen > len ) {
1869  return USER_PACKSTRUCT_INPUT_ERR;
1870  }
1871  }
1872  memcpy( outPtr, inPtr, inLen );
1873  }
1874  inPtr = static_cast<const char*>(inPtr) + inLen + endTagLen;
1875  outPtr = static_cast<char*>(outPtr) + len;
1876 
1877  return 0;
1878 }
1879 
1880 int
1881 unpackString( const void *&inPtr, packedOutput_t &unpackedOutput, int maxStrLen,
1882  const char* name, irodsProt_t irodsProt, char *&outStr ) {
1883  int status;
1884 
1885  if ( irodsProt == XML_PROT ) {
1886  status = unpackXmlString( inPtr, unpackedOutput, maxStrLen,
1887  name, outStr );
1888  }
1889  else {
1890  status = unpackNatString( inPtr, unpackedOutput, maxStrLen, outStr );
1891  }
1892  return status;
1893 }
1894 
1895 int
1896 unpackNatString( const void *&inPtr, packedOutput_t &unpackedOutput, int maxStrLen,
1897  char *&outStr ) {
1898  int myStrlen = inPtr ? strlen( static_cast<const char*>(inPtr) ) : 0;
1899  int extLen = maxStrLen;
1900  void *outPtr;
1901  if ( myStrlen + 1 >= maxStrLen ) {
1902  if ( maxStrLen >= 0 ) {
1903  return USER_PACKSTRUCT_INPUT_ERR;
1904  }
1905  else {
1906  extLen = myStrlen + 1;
1907  }
1908  }
1909 
1910  int status = extendPackedOutput( unpackedOutput, extLen, outPtr );
1911  if ( SYS_MALLOC_ERR == status ) {
1912  return status;
1913  }
1914 
1915  if ( myStrlen == 0 ) {
1916  memset( outPtr, 0, 1 );
1917  }
1918  else {
1919  strncpy( static_cast<char*>(outPtr), static_cast<const char*>(inPtr), myStrlen + 1 );
1920  outStr = static_cast<char*>(outPtr);
1921  }
1922 
1923  if ( maxStrLen > 0 ) {
1924  inPtr = static_cast<const char*>(inPtr) + ( myStrlen + 1 );
1925  unpackedOutput.bBuf.len += maxStrLen;
1926  }
1927  else {
1928  inPtr = static_cast<const char*>(inPtr) + ( myStrlen + 1 );
1929  unpackedOutput.bBuf.len += myStrlen + 1;
1930  }
1931 
1932  return 0;
1933 }
1934 
1935 int
1936 unpackXmlString( const void *&inPtr, packedOutput_t &unpackedOutput, int maxStrLen,
1937  const char* name, char *&outStr ) {
1938  int myStrlen;
1939  void *outPtr;
1940 
1941  int endTagLen;
1942  int origStrLen = parseXmlValue( inPtr, name, endTagLen );
1943  if ( origStrLen < 0 ) {
1944  return origStrLen;
1945  }
1946 
1947  int extLen = maxStrLen;
1948  char* strBuf;
1949  myStrlen = xmlStrToStr( ( const char * )inPtr, origStrLen, strBuf );
1950 
1951  if ( myStrlen >= maxStrLen ) {
1952  if ( maxStrLen >= 0 ) {
1953  free(strBuf);
1954  return USER_PACKSTRUCT_INPUT_ERR;
1955  }
1956  else {
1957  extLen = myStrlen;
1958  }
1959  }
1960 
1961  int status = extendPackedOutput( unpackedOutput, extLen, outPtr );
1962  if ( SYS_MALLOC_ERR == status ) {
1963  free( strBuf );
1964  return status;
1965  }
1966 
1967  if ( myStrlen > 0 ) {
1968  strncpy( static_cast<char*>(outPtr), strBuf, myStrlen );
1969  outStr = static_cast<char*>(outPtr);
1970  outPtr = static_cast<char*>(outPtr) + myStrlen;
1971  }
1972  *static_cast<char*>(outPtr) = '\0';
1973  free(strBuf);
1974 
1975  inPtr = static_cast<const char*>(inPtr) + ( origStrLen + 1 );
1976  if ( maxStrLen > 0 ) {
1977  unpackedOutput.bBuf.len += maxStrLen;
1978  }
1979  else {
1980  unpackedOutput.bBuf.len += myStrlen + 1;
1981  }
1982 
1983  return 0;
1984 }
1985 
1986 int
1987 unpackStringToOutPtr( const void *&inPtr, void *&outPtr, int maxStrLen,
1988  const char* name, irodsProt_t irodsProt ) {
1989  int status;
1990 
1991  if ( irodsProt == XML_PROT ) {
1992  status = unpackXmlStringToOutPtr( inPtr, outPtr, maxStrLen,
1993  name );
1994  }
1995  else {
1996  status = unpackNatStringToOutPtr( inPtr, outPtr, maxStrLen );
1997  }
1998  return status;
1999 }
2000 
2001 /* unpackNullString - check if *inPtr points to a NULL string.
2002  * If it is, put a NULL pointer in unpackedOutput and returns 0.
2003  * Otherwise, returns 1.
2004  */
2005 
2006 int
2007 unpackNullString( const void *&inPtr, packedOutput_t &unpackedOutput,
2008  const packItem_t &myPackedItem, irodsProt_t irodsProt ) {
2009 
2010  if ( inPtr == NULL ) {
2011  /* add a null pointer */
2012  addPointerToPackedOut( unpackedOutput, 0, NULL );
2013  return 0;
2014  }
2015 
2016  const char *myPtr = ( const char* )inPtr;
2017  if ( irodsProt == XML_PROT ) {
2018 
2019  /* check if tag exists */
2020  int skipLen = 0;
2021  int tagLen = parseXmlTag( inPtr, myPackedItem.name, START_TAG_FL,
2022  skipLen );
2023  if ( tagLen < 0 ) {
2024  addPointerToPackedOut( unpackedOutput, 0, NULL );
2025  return 0;
2026  }
2027  else {
2028  myPtr = myPtr + tagLen + skipLen;
2029  }
2030  }
2031  else {
2032  if ( strcmp( ( const char* )inPtr, NULL_PTR_PACK_STR ) == 0 ) {
2033  int myStrlen = strlen( NULL_PTR_PACK_STR );
2034  addPointerToPackedOut( unpackedOutput, 0, NULL );
2035  inPtr = ( const char * )inPtr + ( myStrlen + 1 );
2036  return 0;
2037  }
2038  }
2039  /* need to do more checking for null */
2040  int myDim = myPackedItem.dim;
2041  int numPointer = getNumElement( myPackedItem );
2042  int numElement = getNumHintElement( myPackedItem );
2043 
2044  if ( numElement <= 0 || ( myDim > 0 && numPointer <= 0 ) ) {
2045  /* add a null pointer */
2046  addPointerToPackedOut( unpackedOutput, 0, NULL );
2047  if ( irodsProt == XML_PROT ) {
2048  if ( strncmp( myPtr, "</", 2 ) == 0 ) {
2049  myPtr += 2;
2050  int nameLen = strlen( myPackedItem.name );
2051  if ( strncmp( myPtr, myPackedItem.name, nameLen ) == 0 ) {
2052  myPtr += ( nameLen + 1 );
2053  if ( *myPtr == '\n' ) {
2054  myPtr++;
2055  }
2056  inPtr = myPtr;
2057  }
2058  }
2059  }
2060  return 0;
2061  }
2062  else {
2063  return 1;
2064  }
2065 }
2066 
2067 int
2068 unpackInt( const void *&inPtr, packedOutput_t &unpackedOutput, int numElement,
2069  const char* name, irodsProt_t irodsProt ) {
2070  if ( numElement == 0 ) {
2071  return 0;
2072  }
2073 
2074  void *outPtr;
2075  extendPackedOutput( unpackedOutput, sizeof( int ) * ( numElement + 1 ), outPtr );
2076 
2077  int intValue = unpackIntToOutPtr( inPtr, outPtr, numElement, name, irodsProt );
2078 
2079  /* adjust len */
2080  unpackedOutput.bBuf.len = static_cast<int>(static_cast<char*>(outPtr) - static_cast<char*>(unpackedOutput.bBuf.buf)) + (sizeof(int) * numElement);
2081 
2082  if ( intValue < 0 ) {
2083  /* prevent error exit */
2084  intValue = 0;
2085  }
2086 
2087  return intValue;
2088 }
2089 
2090 int
2091 unpackIntToOutPtr( const void *&inPtr, void *&outPtr, int numElement,
2092  const char* name, irodsProt_t irodsProt ) {
2093  int status;
2094 
2095  if ( irodsProt == XML_PROT ) {
2096  status = unpackXmlIntToOutPtr( inPtr, outPtr, numElement, name );
2097  }
2098  else {
2099  status = unpackNatIntToOutPtr( inPtr, outPtr, numElement );
2100  }
2101  return status;
2102 }
2103 
2104 int
2105 unpackNatIntToOutPtr( const void *&inPtr, void *&outPtr, int numElement ) {
2106  int *tmpIntPtr, *origIntPtr;
2107  int i;
2108  int intValue = 0;
2109 
2110  if ( numElement == 0 ) {
2111  return 0;
2112  }
2113 
2114  const void* inIntPtr = inPtr;
2115 
2116  origIntPtr = tmpIntPtr = ( int * ) malloc( sizeof( int ) * numElement );
2117 
2118  if ( inIntPtr == NULL ) {
2119  /* a NULL pointer, fill the array with 0 */
2120  memset( origIntPtr, 0, sizeof( int ) * numElement );
2121  }
2122  else {
2123  for ( i = 0; i < numElement; i++ ) {
2124  int tmpInt;
2125 
2126  memcpy( &tmpInt, inIntPtr, sizeof( int ) );
2127  *tmpIntPtr = htonl( tmpInt );
2128  if ( i == 0 ) {
2129  /* save this and return later */
2130  intValue = *tmpIntPtr;
2131  }
2132  tmpIntPtr ++;
2133  inIntPtr = ( const char * )inIntPtr + sizeof( int );
2134  }
2135  inPtr = inIntPtr;
2136  }
2137 
2138  /* align unpackedOutput to 4 bytes boundary. Will not align inPtr */
2139 
2140  outPtr = alignInt( outPtr );
2141 
2142  memcpy( outPtr, origIntPtr, sizeof( int ) * numElement );
2143  free( origIntPtr );
2144 
2145  return intValue;
2146 }
2147 
2148 int
2149 unpackXmlIntToOutPtr( const void *&inPtr, void *&outPtr, int numElement,
2150  const char* name ) {
2151  int *tmpIntPtr;
2152  int i;
2153  int myStrlen;
2154  int intValue = 0;
2155 
2156  if ( numElement == 0 ) {
2157  return 0;
2158  }
2159 
2160  /* align outPtr to 4 bytes boundary. Will not align inPtr */
2161 
2162  outPtr = tmpIntPtr = ( int* )alignInt( outPtr );
2163 
2164  if ( inPtr == NULL ) {
2165  /* a NULL pointer, fill the array with 0 */
2166  memset( outPtr, 0, sizeof( int ) * numElement );
2167  }
2168  else {
2169  char tmpStr[NAME_LEN];
2170 
2171  for ( i = 0; i < numElement; i++ ) {
2172  int endTagLen = 0;
2173  myStrlen = parseXmlValue( inPtr, name, endTagLen );
2174  if ( myStrlen < 0 ) {
2175  return myStrlen;
2176  }
2177  else if ( myStrlen >= NAME_LEN ) {
2178  rodsLog( LOG_ERROR,
2179  "unpackXmlIntToOutPtr: input %s with value %s too long",
2180  name, inPtr );
2181  return USER_PACKSTRUCT_INPUT_ERR;
2182  }
2183  strncpy( tmpStr, ( const char* )inPtr, myStrlen );
2184  tmpStr[myStrlen] = '\0';
2185 
2186  *tmpIntPtr = atoi( tmpStr );
2187  if ( i == 0 ) {
2188  /* save this and return later */
2189  intValue = *tmpIntPtr;
2190  }
2191  tmpIntPtr ++;
2192  inPtr = ( const char * )inPtr + ( myStrlen + endTagLen );
2193  }
2194  }
2195  return intValue;
2196 }
2197 
2198 int
2199 unpackInt16( const void *&inPtr, packedOutput_t &unpackedOutput, int numElement,
2200  const char* name, irodsProt_t irodsProt ) {
2201  void *outPtr;
2202  short intValue = 0;
2203 
2204  if ( numElement == 0 ) {
2205  return 0;
2206  }
2207 
2208  extendPackedOutput( unpackedOutput, sizeof( short ) * ( numElement + 1 ),
2209  outPtr );
2210 
2211  intValue = unpackInt16ToOutPtr( inPtr, outPtr, numElement, name,
2212  irodsProt );
2213 
2214  /* adjust len */
2215  unpackedOutput.bBuf.len = static_cast<int>(static_cast<char*>(outPtr) - static_cast<char*>(unpackedOutput.bBuf.buf)) + (sizeof( short ) * numElement);
2216 
2217  if ( intValue < 0 ) {
2218  /* prevent error exit */
2219  intValue = 0;
2220  }
2221 
2222  return intValue;
2223 }
2224 
2225 int
2226 unpackInt16ToOutPtr( const void *&inPtr, void *&outPtr, int numElement,
2227  const char* name, irodsProt_t irodsProt ) {
2228  int status;
2229 
2230  if ( irodsProt == XML_PROT ) {
2231  status = unpackXmlInt16ToOutPtr( inPtr, outPtr, numElement, name );
2232  }
2233  else {
2234  status = unpackNatInt16ToOutPtr( inPtr, outPtr, numElement );
2235  }
2236  return status;
2237 }
2238 
2239 int
2240 unpackNatInt16ToOutPtr( const void *&inPtr, void *&outPtr, int numElement ) {
2241  short *tmpIntPtr, *origIntPtr;
2242  int i;
2243  short intValue = 0;
2244 
2245  if ( numElement == 0 ) {
2246  return 0;
2247  }
2248 
2249  const void* inIntPtr = inPtr;
2250 
2251  origIntPtr = tmpIntPtr = ( short * ) malloc( sizeof( short ) * numElement );
2252 
2253  if ( inIntPtr == NULL ) {
2254  /* a NULL pointer, fill the array with 0 */
2255  memset( origIntPtr, 0, sizeof( short ) * numElement );
2256  }
2257  else {
2258  for ( i = 0; i < numElement; i++ ) {
2259  short tmpInt;
2260 
2261  memcpy( &tmpInt, inIntPtr, sizeof( short ) );
2262  *tmpIntPtr = htons( tmpInt );
2263  if ( i == 0 ) {
2264  /* save this and return later */
2265  intValue = *tmpIntPtr;
2266  }
2267  tmpIntPtr ++;
2268  inIntPtr = ( char * ) inIntPtr + sizeof( short );
2269  }
2270  inPtr = inIntPtr;
2271  }
2272 
2273  /* align unpackedOutput to 4 bytes boundary. Will not align inPtr */
2274 
2275  outPtr = alignInt16( outPtr );
2276 
2277  memcpy( outPtr, origIntPtr, sizeof( short ) * numElement );
2278  free( origIntPtr );
2279 
2280  return intValue;
2281 }
2282 
2283 int
2284 unpackXmlInt16ToOutPtr( const void *&inPtr, void *&outPtr, int numElement,
2285  const char* name ) {
2286  short *tmpIntPtr;
2287  int i;
2288  int myStrlen;
2289  short intValue = 0;
2290 
2291  if ( numElement == 0 ) {
2292  return 0;
2293  }
2294 
2295  /* align outPtr to 4 bytes boundary. Will not align inPtr */
2296 
2297  outPtr = tmpIntPtr = ( short* )alignInt16( outPtr );
2298 
2299  if ( inPtr == NULL ) {
2300  /* a NULL pointer, fill the array with 0 */
2301  memset( outPtr, 0, sizeof( short ) * numElement );
2302  }
2303  else {
2304  char tmpStr[NAME_LEN];
2305 
2306  for ( i = 0; i < numElement; i++ ) {
2307  int endTagLen = 0;
2308  myStrlen = parseXmlValue( inPtr, name, endTagLen );
2309  if ( myStrlen < 0 ) {
2310  return myStrlen;
2311  }
2312  else if ( myStrlen >= NAME_LEN ) {
2313  rodsLog( LOG_ERROR,
2314  "unpackXmlIntToOutPtr: input %s with value %s too long",
2315  name, inPtr );
2316  return USER_PACKSTRUCT_INPUT_ERR;
2317  }
2318  strncpy( tmpStr, ( const char* )inPtr, myStrlen );
2319  tmpStr[myStrlen] = '\0';
2320 
2321  *tmpIntPtr = atoi( tmpStr );
2322  if ( i == 0 ) {
2323  /* save this and return later */
2324  intValue = *tmpIntPtr;
2325  }
2326  tmpIntPtr ++;
2327  inPtr = ( const char * )inPtr + ( myStrlen + endTagLen );
2328  }
2329  }
2330  return intValue;
2331 }
2332 
2333 int
2334 unpackDouble( const void *&inPtr, packedOutput_t &unpackedOutput, int numElement,
2335  const char* name, irodsProt_t irodsProt ) {
2336  void *outPtr;
2337 
2338  if ( numElement == 0 ) {
2339  return 0;
2340  }
2341 
2342  extendPackedOutput( unpackedOutput, sizeof( rodsLong_t ) * ( numElement + 1 ),
2343  outPtr );
2344 
2345  unpackDoubleToOutPtr( inPtr, outPtr, numElement, name, irodsProt );
2346 
2347  /* adjust len */
2348  unpackedOutput.bBuf.len = static_cast<int>(static_cast<char*>(outPtr) - static_cast<char*>(unpackedOutput.bBuf.buf)) + (sizeof(rodsLong_t) * numElement);
2349 
2350  return 0;
2351 }
2352 
2353 int
2354 unpackDoubleToOutPtr( const void *&inPtr, void *&outPtr, int numElement,
2355  const char* name, irodsProt_t irodsProt ) {
2356  int status;
2357 
2358  if ( irodsProt == XML_PROT ) {
2359  status = unpackXmlDoubleToOutPtr( inPtr, outPtr, numElement,
2360  name );
2361  }
2362  else {
2363  status = unpackNatDoubleToOutPtr( inPtr, outPtr, numElement );
2364  }
2365  return status;
2366 }
2367 
2368 int
2369 unpackNatDoubleToOutPtr( const void *&inPtr, void *&outPtr, int numElement ) {
2370  rodsLong_t *tmpDoublePtr, *origDoublePtr;
2371  int i;
2372 
2373  if ( numElement == 0 ) {
2374  return 0;
2375  }
2376 
2377  const void* inDoublePtr = inPtr;
2378 
2379  origDoublePtr = tmpDoublePtr = ( rodsLong_t * ) malloc(
2380  sizeof( rodsLong_t ) * numElement );
2381 
2382  if ( inDoublePtr == NULL ) {
2383  /* a NULL pointer, fill the array with 0 */
2384  memset( origDoublePtr, 0, sizeof( rodsLong_t ) * numElement );
2385  }
2386  else {
2387  for ( i = 0; i < numElement; i++ ) {
2388  rodsLong_t tmpDouble;
2389 
2390  memcpy( &tmpDouble, inDoublePtr, sizeof( rodsLong_t ) );
2391 
2392  myNtohll( tmpDouble, tmpDoublePtr );
2393  tmpDoublePtr ++;
2394  inDoublePtr = ( const char * ) inDoublePtr + sizeof( rodsLong_t );
2395  }
2396  inPtr = inDoublePtr;
2397  }
2398  /* align inPtr to 8 bytes boundary. Will not align outPtr */
2399 
2400 #if defined(osx_platform)
2401  /* osx does not align */
2402  outPtr = alignInt( outPtr );
2403 #else
2404  outPtr = alignDouble( outPtr );
2405 #endif
2406 
2407  memcpy( outPtr, origDoublePtr, sizeof( rodsLong_t ) * numElement );
2408  free( origDoublePtr );
2409 
2410  return 0;
2411 }
2412 
2413 int
2414 unpackXmlDoubleToOutPtr( const void *&inPtr, void *&outPtr, int numElement,
2415  const char* name ) {
2416  rodsLong_t *tmpDoublePtr;
2417  int i;
2418  int myStrlen;
2419 
2420  if ( numElement == 0 ) {
2421  return 0;
2422  }
2423 
2424  /* align inPtr to 8 bytes boundary. Will not align outPtr */
2425 
2426 #if defined(osx_platform)
2427  /* osx does not align */
2428  outPtr = tmpDoublePtr = ( rodsLong_t* )alignInt( outPtr );
2429 #else
2430  outPtr = tmpDoublePtr = ( rodsLong_t* )alignDouble( outPtr );
2431 #endif
2432 
2433  if ( inPtr == NULL ) {
2434  /* a NULL pointer, fill the array with 0 */
2435  memset( outPtr, 0, sizeof( rodsLong_t ) * numElement );
2436  }
2437  else {
2438  for ( i = 0; i < numElement; i++ ) {
2439  char tmpStr[NAME_LEN];
2440 
2441  int endTagLen = 0;
2442  myStrlen = parseXmlValue( inPtr, name, endTagLen );
2443  if ( myStrlen < 0 ) {
2444  return myStrlen;
2445  }
2446  else if ( myStrlen >= NAME_LEN ) {
2447  rodsLog( LOG_ERROR,
2448  "unpackXmlDoubleToOutPtr: input %s with value %s too long",
2449  name, inPtr );
2450  return USER_PACKSTRUCT_INPUT_ERR;
2451  }
2452  strncpy( tmpStr, ( const char* )inPtr, myStrlen );
2453  tmpStr[myStrlen] = '\0';
2454 
2455  *tmpDoublePtr = strtoll( tmpStr, 0, 0 );
2456  tmpDoublePtr ++;
2457  inPtr = ( const char * )inPtr + ( myStrlen + endTagLen );
2458  }
2459  }
2460 
2461  return 0;
2462 }
2463 
2464 int
2465 unpackChildStruct( const void *&inPtr, packedOutput_t &unpackedOutput,
2466  const packItem_t &myPackedItem, const packInstruct_t *myPackTable, int numElement,
2467  irodsProt_t irodsProt, const char *packInstructInp ) {
2468 #if defined(solaris_platform)
2469  int doubleInStruct = 0;
2470 #endif
2471 #if defined(solaris_platform)
2472  void *outPtr1, *outPtr2;
2473 #endif
2474 
2475  if ( numElement == 0 ) {
2476  return 0;
2477  }
2478 
2479  if ( packInstructInp == NULL ) {
2480  packInstructInp = matchPackInstruct( myPackedItem.name, myPackTable );
2481  }
2482 
2483  if ( packInstructInp == NULL ) {
2484  rodsLog( LOG_ERROR,
2485  "unpackChildStruct: matchPackInstruct failed for %s",
2486  myPackedItem.name );
2487  return SYS_UNMATCH_PACK_INSTRUCTI_NAME;
2488  }
2489 
2490  for ( int i = 0; i < numElement; i++ ) {
2491  packItem_t unpackItemHead{};
2492 
2493  int status = parsePackInstruct( packInstructInp, unpackItemHead );
2494  if ( status < 0 ) {
2495  freePackedItem( unpackItemHead );
2496  return status;
2497  }
2498  /* link it */
2499  unpackItemHead.parent = &myPackedItem;
2500 
2501  if ( irodsProt == XML_PROT ) {
2502  int skipLen = 0;
2503  int status = parseXmlTag( inPtr, myPackedItem.name, START_TAG_FL | LF_FL,
2504  skipLen );
2505  if ( status >= 0 ) {
2506  inPtr = ( const char * )inPtr + status + skipLen;
2507  }
2508  else {
2509  if ( myPackedItem.pointerType > 0 ) {
2510  /* a null pointer */
2511  addPointerToPackedOut( unpackedOutput, 0, NULL );
2512  continue;
2513  }
2514  else {
2515  return status;
2516  }
2517  }
2518  }
2519 
2520  /* now unpack each child item */
2521 
2522 #if defined(solaris_platform)
2523  doubleInStruct = 0;
2524 #endif
2525  packItem_t* tmpItem = &unpackItemHead;
2526  while ( tmpItem != NULL ) {
2527 #if defined(solaris_platform)
2528  if ( tmpItem->pointerType == 0 &&
2529  packTypeTable[tmpItem->typeInx].number == PACK_DOUBLE_TYPE ) {
2530  doubleInStruct = 1;
2531  }
2532 #endif
2533  int status = unpackItem( *tmpItem, inPtr, unpackedOutput,
2534  myPackTable, irodsProt );
2535  if ( status < 0 ) {
2536  return status;
2537  }
2538  tmpItem = tmpItem->next;
2539  }
2540  freePackedItem( unpackItemHead );
2541 #if defined(solaris_platform)
2542  /* seems that solaris align to 64 bit boundary if there is any
2543  * double in struct */
2544  if ( doubleInStruct > 0 ) {
2545  extendPackedOutput( unpackedOutput, sizeof( rodsLong_t ), &outPtr1 );
2546  outPtr2 = alignDouble( outPtr1 );
2547  unpackedOutput.bBuf.len += ( ( int ) outPtr2 - ( int ) outPtr1 );
2548  }
2549 #endif
2550  if ( irodsProt == XML_PROT ) {
2551  int skipLen = 0;
2552  int status = parseXmlTag( inPtr, myPackedItem.name, END_TAG_FL | LF_FL,
2553  skipLen );
2554  if ( status >= 0 ) {
2555  inPtr = ( const char * )inPtr + status + skipLen;
2556  }
2557  else {
2558  return status;
2559  }
2560  }
2561  }
2562  return 0;
2563 }
2564 
2565 int
2566 unpackPointerItem( packItem_t &myPackedItem, const void *&inPtr,
2567  packedOutput_t &unpackedOutput, const packInstruct_t *myPackTable,
2568  irodsProt_t irodsProt ) {
2569  int i = 0, j = 0, status = 0;
2570  void **pointerArray = nullptr;
2571  void *outPtr = nullptr;
2572 
2573  if ( unpackNullString( inPtr, unpackedOutput, myPackedItem, irodsProt )
2574  <= 0 ) {
2575  /* a null pointer and has been handled */
2576  return 0;
2577  }
2578 
2579  int myDim = myPackedItem.dim;
2580  int typeInx = myPackedItem.typeInx;
2581  int numPointer = getNumElement( myPackedItem );
2582  int numElement = getNumHintElement( myPackedItem );
2583  int elementSz = packTypeTable[typeInx].size;
2584  int myTypeNum = packTypeTable[typeInx].number;
2585 
2586  /* alloc pointer to an array of pointers if myDim > 0 */
2587  if ( myDim > 0 ) {
2588  if ( numPointer > 0 ) {
2589  int allocLen, myModu;
2590 
2591  /* allocate at PTR_ARRAY_MALLOC_LEN boundary */
2592  if ( ( myModu = numPointer % PTR_ARRAY_MALLOC_LEN ) == 0 ) {
2593  allocLen = numPointer;
2594  }
2595  else {
2596  allocLen = numPointer + PTR_ARRAY_MALLOC_LEN - myModu;
2597  }
2598  if ( myTypeNum == PACK_DOUBLE_TYPE || myTypeNum == PACK_INT_TYPE ||
2599  myTypeNum == PACK_INT16_TYPE ) {
2600  /* pointer to an array of int or double */
2601  pointerArray = static_cast<void**>(addPointerToPackedOut(unpackedOutput, allocLen * elementSz, NULL));
2602  }
2603  else {
2604  pointerArray = static_cast<void**>(addPointerToPackedOut(unpackedOutput, allocLen * sizeof(void*), NULL));
2605  }
2606  }
2607  else {
2608  return 0;
2609  }
2610  }
2611  else if ( myDim < 0 ) {
2612  return SYS_NEGATIVE_SIZE;
2613  }
2614 
2615  switch ( myTypeNum ) {
2616  case PACK_CHAR_TYPE:
2617  case PACK_BIN_TYPE:
2618  if ( myDim == 0 ) {
2619  if ( myPackedItem.pointerType == NO_PACK_POINTER ) {
2620  }
2621  else {
2622  outPtr = addPointerToPackedOut( unpackedOutput,
2623  numElement * elementSz, NULL );
2624  status = unpackCharToOutPtr( inPtr, outPtr,
2625  numElement * elementSz, myPackedItem.name, myPackedItem.typeInx, irodsProt );
2626  }
2627 
2628  if ( status < 0 ) {
2629  return status;
2630  }
2631  }
2632  else {
2633  /* pointer to an array of pointers */
2634  for ( i = 0; i < numPointer; i++ ) {
2635  if ( myPackedItem.pointerType != NO_PACK_POINTER ) {
2636  outPtr = pointerArray[i] = malloc( numElement * elementSz );
2637  status = unpackCharToOutPtr( inPtr, outPtr,
2638  numElement * elementSz, myPackedItem.name, myPackedItem.typeInx, irodsProt );
2639  }
2640  if ( status < 0 ) {
2641  return status;
2642  }
2643  }
2644  }
2645  break;
2646  case PACK_STR_TYPE:
2647  case PACK_PI_STR_TYPE: {
2648  /* the size of the last dim is the max length of the string. Don't
2649  * want to unpack the entire length, just to end of the string
2650  * including the NULL.
2651  */
2652  int maxStrLen = 0, numStr = 0, myLen = 0;
2653 
2654  getNumStrAndStrLen( myPackedItem, numStr, maxStrLen );
2655 
2656  if ( maxStrLen == 0 ) {
2657  /* add a null pointer mw. 9/15/06 */
2658  /* this check is probably not needed since it has been handled
2659  by numElement == 0 */
2660  outPtr = addPointerToPackedOut( unpackedOutput, 0, NULL );
2661  return 0;
2662  }
2663 
2664  if ( myDim == 0 ) {
2665  char *myOutStr;
2666 
2667  myLen = getAllocLenForStr( myPackedItem, inPtr, numStr, maxStrLen );
2668  if ( myLen < 0 ) {
2669  return myLen;
2670  }
2671 
2672  outPtr = addPointerToPackedOut( unpackedOutput, myLen, NULL );
2673  myOutStr = static_cast<char*>(outPtr);
2674  for ( i = 0; i < numStr; i++ ) {
2675  status = unpackStringToOutPtr(
2676  inPtr, outPtr, maxStrLen, myPackedItem.name, irodsProt );
2677  if ( status < 0 ) {
2678  return status;
2679  }
2680  if ( myTypeNum == PACK_PI_STR_TYPE && i == 0 &&
2681  myOutStr != NULL ) {
2682  strncpy( myPackedItem.strValue, myOutStr, NAME_LEN );
2683  }
2684  }
2685  }
2686  else {
2687  for ( j = 0; j < numPointer; j++ ) {
2688  myLen = getAllocLenForStr( myPackedItem, inPtr, numStr,
2689  maxStrLen );
2690  if ( myLen < 0 ) {
2691  return myLen;
2692  }
2693  outPtr = pointerArray[j] = malloc( myLen );
2694  for ( i = 0; i < numStr; i++ ) {
2695  status = unpackStringToOutPtr(
2696  inPtr, outPtr, maxStrLen, myPackedItem.name, irodsProt );
2697  if ( status < 0 ) {
2698  return status;
2699  }
2700  }
2701  }
2702  }
2703  break;
2704  }
2705  case PACK_INT_TYPE:
2706  if ( myDim == 0 ) {
2707  outPtr = addPointerToPackedOut( unpackedOutput,
2708  numElement * elementSz, NULL );
2709  status = unpackIntToOutPtr( inPtr, outPtr, numElement,
2710  myPackedItem.name, irodsProt );
2711  /* don't chk status. It could be a -ive int */
2712  }
2713  else {
2714  /* pointer to an array of pointers */
2715  for ( i = 0; i < numPointer; i++ ) {
2716  outPtr = pointerArray[i] = malloc( numElement * elementSz );
2717  status = unpackIntToOutPtr( inPtr, outPtr,
2718  numElement * elementSz, myPackedItem.name, irodsProt );
2719  if ( status < 0 ) {
2720  return status;
2721  }
2722  }
2723  }
2724  break;
2725  case PACK_INT16_TYPE:
2726  if ( myDim == 0 ) {
2727  outPtr = addPointerToPackedOut( unpackedOutput,
2728  numElement * elementSz, NULL );
2729  status = unpackInt16ToOutPtr( inPtr, outPtr, numElement,
2730  myPackedItem.name, irodsProt );
2731  /* don't chk status. It could be a -ive int */
2732  }
2733  else {
2734  /* pointer to an array of pointers */
2735  for ( i = 0; i < numPointer; i++ ) {
2736  outPtr = pointerArray[i] = malloc( numElement * elementSz );
2737  status = unpackInt16ToOutPtr( inPtr, outPtr,
2738  numElement * elementSz, myPackedItem.name, irodsProt );
2739  if ( status < 0 ) {
2740  return status;
2741  }
2742  }
2743  }
2744  break;
2745  case PACK_DOUBLE_TYPE:
2746  if ( myDim == 0 ) {
2747  outPtr = addPointerToPackedOut( unpackedOutput,
2748  numElement * elementSz, NULL );
2749  status = unpackDoubleToOutPtr( inPtr, outPtr, numElement,
2750  myPackedItem.name, irodsProt );
2751  /* don't chk status. It could be a -ive int */
2752  }
2753  else {
2754  /* pointer to an array of pointers */
2755  for ( i = 0; i < numPointer; i++ ) {
2756  outPtr = pointerArray[i] = malloc( numElement * elementSz );
2757  status = unpackDoubleToOutPtr( inPtr, outPtr,
2758  numElement * elementSz, myPackedItem.name, irodsProt );
2759  if ( status < 0 ) {
2760  return status;
2761  }
2762  }
2763  }
2764 
2765  break;
2766 
2767  case PACK_STRUCT_TYPE: {
2768  /* no need to align boundary for struct */
2769 
2770  if ( myDim == 0 ) {
2771  /* we really don't know the size of each struct. */
2772  /* outPtr = addPointerToPackedOut (unpackedOutput,
2773  numElement * SUB_STRUCT_ALLOC_SZ); */
2774  outPtr = malloc( numElement * SUB_STRUCT_ALLOC_SZ );
2775  packedOutput_t subPackedOutput = initPackedOutputWithBuf( outPtr, numElement * SUB_STRUCT_ALLOC_SZ );
2776  status = unpackChildStruct( inPtr, subPackedOutput, myPackedItem, myPackTable, numElement, irodsProt, NULL );
2777  addPointerToPackedOut( unpackedOutput, numElement * SUB_STRUCT_ALLOC_SZ, subPackedOutput.bBuf.buf );
2778  subPackedOutput.bBuf.buf = NULL;
2779  if ( status < 0 ) {
2780  return status;
2781  }
2782  }
2783  else {
2784  /* pointer to an array of pointers */
2785  for ( i = 0; i < numPointer; i++ ) {
2786  /* outPtr = pointerArray[i] = malloc ( */
2787  outPtr = malloc(
2788  numElement * SUB_STRUCT_ALLOC_SZ );
2789  packedOutput_t subPackedOutput = initPackedOutputWithBuf( outPtr, numElement * SUB_STRUCT_ALLOC_SZ );
2790  status = unpackChildStruct( inPtr, subPackedOutput, myPackedItem, myPackTable, numElement, irodsProt, NULL );
2791  pointerArray[i] = subPackedOutput.bBuf.buf;
2792  subPackedOutput.bBuf.buf = NULL;
2793  if ( status < 0 ) {
2794  return status;
2795  }
2796  }
2797  }
2798  break;
2799  }
2800  default:
2801  rodsLog( LOG_ERROR,
2802  "unpackPointerItem: Unknown type %d - %s ",
2803  myTypeNum, myPackedItem.name );
2804 
2805  return SYS_PACK_INSTRUCT_FORMAT_ERR;
2806  }
2807 
2808  return 0;
2809 }
2810 
2811 void *
2812 addPointerToPackedOut( packedOutput_t &packedOutput, int len, void *pointer ) {
2813  void *outPtr;
2814  extendPackedOutput( packedOutput, sizeof(void*), outPtr );
2815  outPtr = ialignAddr( outPtr );
2816 
2817  void** tmpPtr = static_cast<void**>(outPtr);
2818 
2819  if ( pointer != NULL ) {
2820  *tmpPtr = pointer;
2821  }
2822  else if ( len > 0 ) {
2823  *tmpPtr = malloc( len );
2824  memset(*tmpPtr, 0, len);
2825  }
2826  else {
2827  /* add a NULL pointer */
2828  *tmpPtr = NULL;
2829  }
2830 
2831  packedOutput.bBuf.len = static_cast<int>( static_cast<char*>(outPtr) - static_cast<char*>(packedOutput.bBuf.buf)) + sizeof(void*);
2832 
2833  return *tmpPtr;
2834 }
2835 
2836 int
2837 unpackNatStringToOutPtr( const void *&inPtr, void *&outPtr, int maxStrLen ) {
2838  int myStrlen;
2839 
2840  if ( inPtr == NULL ) {
2841  rodsLog( LOG_ERROR,
2842  "unpackStringToOutPtr: NULL inPtr" );
2843  return SYS_PACK_INSTRUCT_FORMAT_ERR;
2844  }
2845  myStrlen = strlen( ( const char* )inPtr );
2846 
2847  /* maxStrLen = -1 means null terminated */
2848  if ( maxStrLen >= 0 && myStrlen >= maxStrLen ) {
2849  return USER_PACKSTRUCT_INPUT_ERR;
2850  }
2851 
2852  rstrcpy( static_cast<char*>(outPtr), static_cast<const char*>(inPtr), myStrlen + 1 );
2853 
2854  inPtr = static_cast<const char*>(inPtr) + ( myStrlen + 1 );
2855 
2856  if ( maxStrLen >= 0 ) {
2857  outPtr = static_cast<char*>(outPtr) + maxStrLen;
2858  }
2859  else {
2860  outPtr = static_cast<char*>(outPtr) + ( myStrlen + 1 );
2861  }
2862 
2863  return 0;
2864 }
2865 
2866 int
2867 unpackXmlStringToOutPtr( const void *&inPtr, void *&outPtr, int maxStrLen,
2868  const char* name ) {
2869 
2870  if ( inPtr == NULL ) {
2871  rodsLog( LOG_ERROR,
2872  "unpackXmlStringToOutPtr: NULL inPtr" );
2873  return SYS_PACK_INSTRUCT_FORMAT_ERR;
2874  }
2875 
2876  int endTagLen = 0;
2877  int origStrLen = parseXmlValue( inPtr, name, endTagLen );
2878  if ( origStrLen < 0 ) {
2879  return origStrLen;
2880  }
2881 
2882  char *myStrPtr;
2883  int myStrlen = xmlStrToStr( ( const char * )inPtr, origStrLen, myStrPtr );
2884 
2885  /* maxStrLen = -1 means null terminated */
2886  if ( maxStrLen >= 0 && myStrlen >= maxStrLen ) {
2887  return USER_PACKSTRUCT_INPUT_ERR;
2888  }
2889 
2890  if ( myStrlen == 0 ) {
2891  memset( outPtr, 0, 1 );
2892  }
2893  else {
2894  strncpy( static_cast<char*>(outPtr), myStrPtr, myStrlen + 1 );
2895  }
2896 
2897  inPtr = static_cast<const char*>(inPtr) + ( origStrLen + endTagLen );
2898 
2899  if ( maxStrLen >= 0 ) {
2900  outPtr = static_cast<char*>(outPtr) + maxStrLen;
2901  }
2902  else {
2903  outPtr = static_cast<char*>(outPtr) + ( myStrlen + 1 );
2904  }
2905 
2906  return 0;
2907 }
2908 
2909 /*
2910  * a maxStrLen of -1 means it is NULL terminated
2911  */
2912 
2913 int
2914 getNumStrAndStrLen( const packItem_t &myPackedItem, int& numStr, int& maxStrLen ) {
2915 
2916  int myHintDim = myPackedItem.hintDim;
2917  if ( myHintDim <= 0 ) { /* just a pointer to a null terminated str */
2918  maxStrLen = -1;
2919  numStr = 1;
2920  }
2921  else {
2922  maxStrLen = myPackedItem.hintDimSize[myHintDim - 1];
2923  if ( maxStrLen <= 0 ) {
2924  numStr = 0;
2925  }
2926  else {
2927  numStr = getNumHintElement( myPackedItem ) / maxStrLen;
2928  }
2929  }
2930 
2931  return 0;
2932 }
2933 
2934 /* getAllocLenForStr - Get the alloc length for unpacking str pointer
2935  *
2936  * A -1 maxStrLen means NULL terminated
2937  */
2938 
2939 int
2940 getAllocLenForStr( const packItem_t &myPackedItem, const void *inPtr, int numStr,
2941  int maxStrLen ) {
2942  int myLen;
2943 
2944  if ( numStr <= 1 ) {
2945  myLen = maxStrLen > 0 ? maxStrLen : strlen( (const char* ) inPtr ) + 1;
2946  }
2947  else {
2948  if ( maxStrLen < 0 ) {
2949  rodsLog( LOG_ERROR,
2950  "unpackPointerItem: maxStrLen < 0 with numStr > 1 for %s",
2951  myPackedItem.name );
2952  return SYS_PACK_INSTRUCT_FORMAT_ERR;
2953  }
2954  myLen = numStr * maxStrLen;
2955  }
2956  return myLen;
2957 }
2958 
2959 int
2960 packXmlTag( const char* name, packedOutput_t &packedOutput,
2961  int flag ) {
2962  void *outPtr;
2963 
2964  /* +5 to include <>, '/', \n and NULL */
2965  int myStrlen = strlen( name ) + 5;
2966  int status = extendPackedOutput( packedOutput, myStrlen, outPtr );
2967  if ( SYS_MALLOC_ERR == status ) {
2968  return status;
2969  }
2970 
2971  if ( flag & END_TAG_FL ) {
2972  snprintf( static_cast<char*>(outPtr), myStrlen, "</%s>\n", name );
2973  }
2974  else {
2975  if ( flag & LF_FL ) {
2976  snprintf( static_cast<char*>(outPtr), myStrlen, "<%s>\n", name );
2977  }
2978  else {
2979  snprintf( static_cast<char*>(outPtr), myStrlen, "<%s>", name );
2980  }
2981  }
2982  packedOutput.bBuf.len += strlen( static_cast<char*>(outPtr) );
2983 
2984  return 0;
2985 }
2986 
2987 int
2988 parseXmlValue( const void *&inPtr, const char* name, int &endTagLen ) {
2989 
2990  if ( inPtr == NULL ) {
2991  return USER__NULL_INPUT_ERR;
2992  }
2993 
2994  int strLen = 0;
2995  int status = parseXmlTag( inPtr, name, START_TAG_FL, strLen );
2996  if ( status >= 0 ) {
2997  /* set inPtr to the beginning of the string value */
2998  inPtr = ( const char * ) inPtr + status + strLen;
2999  }
3000  else {
3001  return status;
3002  }
3003 
3004  strLen = 0;
3005  status = parseXmlTag( inPtr, name, END_TAG_FL | LF_FL, strLen );
3006  if ( status >= 0 ) {
3007  endTagLen = status;
3008  }
3009  else {
3010  return status;
3011  }
3012 
3013  return strLen;
3014 }
3015 
3016 /* parseXmlTag - Parse the str given in *inPtr for the tag given in
3017  * name.
3018  * The flag can be
3019  * START_TAG_FL - look for <name>
3020  * END_TAG_FL - look for </name>
3021  * The LF_FL (line feed) can also be added START_TAG_FL or END_TAG_FL
3022  * to skip a '\n" char after the tag.
3023  * Return the length of the tag, also put the number of char skipped to
3024  * reach the beginning og the tag in *skipLen
3025  */
3026 int
3027 parseXmlTag( const void *inPtr, const char* name, int flag, int &skipLen ) {
3028  const char *tmpPtr;
3029  int nameLen;
3030  int myLen = 0;
3031 
3032  const char* inStrPtr = ( const char * )inPtr;
3033 
3034  nameLen = strlen( name );
3035 
3036  if ( flag & END_TAG_FL ) {
3037  /* end tag */
3038  char endTag[MAX_NAME_LEN];
3039 
3040  snprintf( endTag, MAX_NAME_LEN, "</%s>", name );
3041  if ( ( tmpPtr = strstr( inStrPtr, endTag ) ) == NULL ) {
3042  rodsLog( LOG_ERROR,
3043  "parseXmlTag: XML end tag error for %s, expect </%s>",
3044  inPtr, name );
3046  }
3047 
3048  skipLen = tmpPtr - inStrPtr;
3049 
3050  myLen = nameLen + 3;
3051  inStrPtr = tmpPtr + nameLen + 3;
3052  if ( *inStrPtr == '\n' ) {
3053  myLen++;
3054  }
3055  }
3056  else {
3057  /* start tag */
3058  if ( ( tmpPtr = strstr( inStrPtr, "<" ) ) == NULL ) {
3060  }
3061  skipLen = tmpPtr - inStrPtr;
3062  inStrPtr = tmpPtr + 1;
3063  myLen++;
3064 
3065  if ( strncmp( inStrPtr, name, nameLen ) != 0 ) {
3066  /* this can be normal */
3068  "parseXmlValue: XML start tag error for %s, expect <%s>",
3069  inPtr, name );
3071  }
3072  inStrPtr += nameLen;
3073  myLen += nameLen;
3074 
3075  if ( *inStrPtr != '>' ) {
3077  "parseXmlValue: XML start tag error for %s, expect <%s>",
3078  inPtr, name );
3079 
3081  }
3082 
3083  myLen++;
3084 
3085  inStrPtr ++;
3086  if ( ( flag & LF_FL ) && *inStrPtr == '\n' ) {
3087  myLen++;
3088  }
3089  }
3090 
3091  return myLen;
3092 }
3093 
3094 int
3096  void *outPtr, *alignedOutPtr;
3097 
3098  if ( packedOutput.bBuf.buf == NULL || packedOutput.bBuf.len == 0 ) {
3099  return 0;
3100  }
3101 
3102  outPtr = static_cast<char*>(packedOutput.bBuf.buf) + packedOutput.bBuf.len;
3103 
3104  alignedOutPtr = alignDouble( outPtr );
3105 
3106  if ( alignedOutPtr == outPtr ) {
3107  return 0;
3108  }
3109 
3110  if ( packedOutput.bBuf.len + 8 > packedOutput.bufSize ) {
3111  extendPackedOutput( packedOutput, 8, outPtr );
3112  }
3113  packedOutput.bBuf.len = packedOutput.bBuf.len + 8 - static_cast<int>(static_cast<char*>(alignedOutPtr) - static_cast<char*>(outPtr));
3114 
3115  return 0;
3116 }
3117 
3118 /* packNopackPointer - copy the char pointer in *inPtr into
3119  * packedOutput->nopackBufArray without packing. Pack the buffer index
3120  * into packedOutput as an integer.
3121  */
3122 
3123 int
3124 packNopackPointer( void *inPtr, packedOutput_t &packedOutput, int len,
3125  const char* name, irodsProt_t irodsProt ) {
3126  int newNumBuf;
3127  int curNumBuf;
3128  bytesBuf_t *newBBufArray;
3129  int i;
3130  int status;
3131 
3132  curNumBuf = packedOutput.nopackBufArray.numBuf;
3133  if ( ( curNumBuf % PTR_ARRAY_MALLOC_LEN ) == 0 ) {
3134  newNumBuf = curNumBuf + PTR_ARRAY_MALLOC_LEN;
3135 
3136  newBBufArray = ( bytesBuf_t * ) malloc( newNumBuf * sizeof( bytesBuf_t ) );
3137  memset( newBBufArray, 0, newNumBuf * sizeof( bytesBuf_t ) );
3138  for ( i = 0; i < curNumBuf; i++ ) {
3139  newBBufArray[i].len = packedOutput.nopackBufArray.bBufArray[i].len;
3140  newBBufArray[i].buf = packedOutput.nopackBufArray.bBufArray[i].buf;
3141  }
3142  if ( packedOutput.nopackBufArray.bBufArray != NULL ) {
3143  free( packedOutput.nopackBufArray.bBufArray );
3144  }
3145  packedOutput.nopackBufArray.bBufArray = newBBufArray;
3146  }
3147  packedOutput.nopackBufArray.bBufArray[curNumBuf].len = len;
3148  packedOutput.nopackBufArray.bBufArray[curNumBuf].buf = inPtr;
3149  packedOutput.nopackBufArray.numBuf++;
3150 
3151  const void* intPtr = &curNumBuf;
3152  status = packInt( intPtr, packedOutput, 1, name,
3153  irodsProt );
3154 
3155  if ( status < 0 ) {
3156  return status;
3157  }
3158 
3159  return 0;
3160 }
rodsLog
void rodsLog(int level, const char *formatStr,...)
Definition: rodsLog.cpp:86
NULL
#define NULL
Definition: rodsDef.h:70
packInt
int packInt(const void *&inPtr, packedOutput_t &packedOutput, int numElement, const char *name, irodsProt_t irodsProt)
Definition: packStruct.cpp:1414
SYS_PACK_INSTRUCT_FORMAT_ERR
@ SYS_PACK_INSTRUCT_FORMAT_ERR
Definition: rodsErrorTable.h:83
unpackNonpointerItem
int unpackNonpointerItem(packItem_t &myPackedItem, const void *&inPtr, packedOutput_t &unpackedOutput, const packInstruct_t *myPackTable, irodsProt_t irodsProt)
Definition: packStruct.cpp:1698
SYS_INTERNAL_NULL_INPUT_ERR
@ SYS_INTERNAL_NULL_INPUT_ERR
Definition: rodsErrorTable.h:92
packDouble
int packDouble(const void *&inPtr, packedOutput_t &packedOutput, int numElement, const char *name, irodsProt_t irodsProt)
Definition: packStruct.cpp:1541
packNonpointerItem
int packNonpointerItem(packItem_t &myPackedItem, const void *&inPtr, packedOutput_t &packedOutput, const packInstruct_t *myPackTable, int packFlag, irodsProt_t irodsProt)
Definition: packStruct.cpp:747
START_TAG_FL
#define START_TAG_FL
Definition: packStruct.h:21
PackConstantTable
packConstant_t PackConstantTable[]
Definition: rodsPackTable.h:33
freePackedItem
int freePackedItem(packItem_t &packItemHead)
Definition: packStruct.cpp:1661
alignInt
T alignInt(T ptr)
Definition: alignPointer.hpp:39
BytesBuf::buf
void * buf
Definition: rodsDef.h:199
SYS_MALLOC_ERR
@ SYS_MALLOC_ERR
Definition: rodsErrorTable.h:84
packConstant_t::value
int value
Definition: packStruct.h:39
packInstruct_t
Definition: packStruct.h:31
packItem::next
struct packItem * next
Definition: packStruct.h:92
packChar
int packChar(const void *&inPtr, packedOutput_t &packedOutput, int len, const char *name, const packTypeInx_t typeInx, irodsProt_t irodsProt)
Definition: packStruct.cpp:1154
base64_encode
int base64_encode(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen)
Definition: base64.cpp:45
packItem::hintDim
int hintDim
Definition: packStruct.h:88
packItem::dimSize
int dimSize[20]
Definition: packStruct.h:87
packItem::hintDimSize
int hintDimSize[20]
Definition: packStruct.h:89
packItem
Definition: packStruct.h:79
XML_PROT
@ XML_PROT
Definition: rodsDef.h:149
unpackPointerItem
int unpackPointerItem(packItem_t &myPackedItem, const void *&inPtr, packedOutput_t &unpackedOutput, const packInstruct_t *myPackTable, irodsProt_t irodsProt)
Definition: packStruct.cpp:2566
rcMisc.h
initPackedOutput
packedOutput_t initPackedOutput(const int len)
Definition: packStruct.cpp:347
packItem::name
char * name
Definition: packStruct.h:81
packTypeLookup
int packTypeLookup(const char *typeName)
Definition: packStruct.cpp:335
bytesBufArray_t::bBufArray
bytesBuf_t * bBufArray
Definition: packStruct.h:97
irods::lookup_table< pack_entry >::iterator
irods_hash_map::iterator iterator
Definition: irods_lookup_table.hpp:31
packXmlString
int packXmlString(const void *&inPtr, packedOutput_t &packedOutput, int maxStrLen, const char *name)
Definition: packStruct.cpp:1265
packedOutput_t::nopackBufArray
bytesBufArray_t nopackBufArray
Definition: packStruct.h:103
packItem::parent
const struct packItem * parent
Definition: packStruct.h:90
unpackStruct
int unpackStruct(const void *inPackedStr, void **outStruct, const char *packInstName, const packInstruct_t *myPackTable, irodsProt_t irodsProt)
Definition: packStruct.cpp:63
packType_t::size
int size
Definition: packStruct.h:65
rcGlobalExtern.h
packInt16
int packInt16(const void *&inPtr, packedOutput_t &packedOutput, int numElement, const char *name, irodsProt_t irodsProt)
Definition: packStruct.cpp:1477
LOG_ERROR
#define LOG_ERROR
Definition: rodsLog.h:43
generate_iadmin_commands_for_41_to_42_upgrade.name
name
Definition: generate_iadmin_commands_for_41_to_42_upgrade.py:23
pointer
Definition: parser.hpp:34
packedOutput_t::bBuf
bytesBuf_t bBuf
Definition: packStruct.h:101
packNullString
int packNullString(packedOutput_t &packedOutput)
Definition: packStruct.cpp:1400
resolveStrInItem
int resolveStrInItem(packItem_t &myPackedItem)
Definition: packStruct.cpp:625
irods_pack_table.hpp
BytesBuf::len
int len
Definition: rodsDef.h:198
packItem
int packItem(packItem_t &myPackedItem, const void *&inPtr, packedOutput_t &packedOutput, const packInstruct_t *myPackTable, int packFlag, irodsProt_t irodsProt)
Definition: packStruct.cpp:1132
irodsProt_t
irodsProt_t
Definition: rodsDef.h:147
packTypeTable
packType_t packTypeTable[]
Definition: rodsPackTable.h:18
unpackChildStruct
int unpackChildStruct(const void *&inPtr, packedOutput_t &unpackedOutput, const packItem_t &myPackedItem, const packInstruct_t *myPackTable, int numElement, irodsProt_t irodsProt, const char *packInstructInp)
Definition: packStruct.cpp:2465
matchPackInstruct
const char * matchPackInstruct(const char *name, const packInstruct_t *myPackTable)
Definition: packStruct.cpp:659
MAX_PACK_DIM
#define MAX_PACK_DIM
Definition: packStruct.h:68
packInstruct_t::packInstruct
const char * packInstruct
Definition: packStruct.h:33
getRodsLogLevel
int getRodsLogLevel()
Definition: rodsLog.cpp:344
PACK_CHAR_TYPE
@ PACK_CHAR_TYPE
Definition: packStruct.h:44
base64.h
getNumElement
int getNumElement(const packItem_t &myPackedItem)
Definition: packStruct.cpp:1081
resolveIntInItem
int resolveIntInItem(const char *name, const packItem_t &myPackedItem)
Definition: packStruct.cpp:586
MAX_NAME_LEN
#define MAX_NAME_LEN
Definition: rodsDef.h:61
base64_decode
int base64_decode(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen)
Definition: base64.cpp:91
packType_t::number
packTypeInx_t number
Definition: packStruct.h:64
END_TAG_FL
#define END_TAG_FL
Definition: packStruct.h:22
USER_PACKSTRUCT_INPUT_ERR
@ USER_PACKSTRUCT_INPUT_ERR
Definition: rodsErrorTable.h:239
copyStrFromPiBuf
int copyStrFromPiBuf(const char *&inBuf, char *outBuf, int dependentFlag)
Definition: packStruct.cpp:277
irods.pypyodbc.buffer
buffer
Definition: pypyodbc.py:46
PACK_STR_TYPE
@ PACK_STR_TYPE
Definition: packStruct.h:46
irods::lookup_table::find
iterator find(KeyType _k)
Definition: irods_lookup_table.hpp:65
PACK_INT_TYPE
@ PACK_INT_TYPE
Definition: packStruct.h:48
A_POINTER
#define A_POINTER
Definition: packStruct.h:72
get_irods_version.value
dictionary value
Definition: get_irods_version.py:27
irods.pypyodbc.status
status
Definition: pypyodbc.py:467
parseXmlTag
int parseXmlTag(const void *inPtr, const char *name, int flag, int &skipLen)
Definition: packStruct.cpp:3027
unpackXmlStringToOutPtr
int unpackXmlStringToOutPtr(const void *&inPtr, void *&outPtr, int maxStrLen, const char *name)
Definition: packStruct.cpp:2867
packItem::pointer
const void * pointer
Definition: packStruct.h:83
rodsLog.h
packOpr_t
packOpr_t
Definition: packStruct.h:57
packStruct.h
PACK_INT_DEPENDENT_TYPE
@ PACK_INT_DEPENDENT_TYPE
Definition: packStruct.h:52
LOG_DEBUG9
#define LOG_DEBUG9
Definition: rodsLog.h:20
PACK_DOUBLE_TYPE
@ PACK_DOUBLE_TYPE
Definition: packStruct.h:49
irods::lookup_table::end
iterator end()
Definition: irods_lookup_table.hpp:56
RodsPackTable
const packInstruct_t RodsPackTable[]
Definition: rodsPackTable.h:61
BytesBuf
Definition: rodsDef.h:197
iparseDependent
int iparseDependent(packItem_t &myPackedItem)
Definition: packStruct.cpp:421
packedOutput_t::bufSize
int bufSize
Definition: packStruct.h:102
packTypeInx_t
packTypeInx_t
Definition: packStruct.h:43
packChildStruct
int packChildStruct(const void *&inPtr, packedOutput_t &packedOutput, const packItem_t &myPackedItem, const packInstruct_t *myPackTable, int numElement, int packFlag, irodsProt_t irodsProt, const char *packInstructInp)
Definition: packStruct.cpp:1595
initPackedOutputWithBuf
packedOutput_t initPackedOutputWithBuf(void *buf, const int len)
Definition: packStruct.cpp:359
packStruct
int packStruct(const void *inStruct, bytesBuf_t **packedResult, const char *packInstName, const packInstruct_t *myPackTable, int packFlag, irodsProt_t irodsProt)
Definition: packStruct.cpp:21
LF_FL
#define LF_FL
Definition: packStruct.h:23
unpackXmlIntToOutPtr
int unpackXmlIntToOutPtr(const void *&inPtr, void *&outPtr, int numElement, const char *name)
Definition: packStruct.cpp:2149
MAX_PACKED_OUT_ALLOC_SZ
#define MAX_PACKED_OUT_ALLOC_SZ
Definition: packStruct.h:17
resolveDepInArray
int resolveDepInArray(packItem_t &myPackedItem)
Definition: packStruct.cpp:692
packString
int packString(const void *&inPtr, packedOutput_t &packedOutput, int maxStrLen, const char *name, irodsProt_t irodsProt)
Definition: packStruct.cpp:1211
isAllDigit
int isAllDigit(const char *myStr)
Definition: stringOpr.cpp:209
PACK_PI_STR_TYPE
@ PACK_PI_STR_TYPE
Definition: packStruct.h:47
packNatString
int packNatString(const void *&inPtr, packedOutput_t &packedOutput, int maxStrLen)
Definition: packStruct.cpp:1226
packItem::dim
int dim
Definition: packStruct.h:86
alignPointer.hpp
resolvePackedItem
int resolvePackedItem(packItem_t &myPackedItem, const void *&inPtr, packOpr_t packOpr)
Definition: packStruct.cpp:371
irods::get_pack_table
irods::pack_entry_table & get_pack_table()
Definition: irods_pack_table.cpp:15
packItem::prev
struct packItem * prev
Definition: packStruct.h:91
PTR_ARRAY_MALLOC_LEN
#define PTR_ARRAY_MALLOC_LEN
Definition: rodsDef.h:73
unpackStringToOutPtr
int unpackStringToOutPtr(const void *&inPtr, void *&outPtr, int maxStrLen, const char *name, irodsProt_t irodsProt)
Definition: packStruct.cpp:1987
PACK_TABLE_END_PI
#define PACK_TABLE_END_PI
Definition: packStruct.h:27
packedOutput_t
Definition: packStruct.h:100
alignPackedOutput64
int alignPackedOutput64(packedOutput_t &packedOutput)
Definition: packStruct.cpp:3095
NO_PACK_POINTER
#define NO_PACK_POINTER
Definition: packStruct.h:74
ialignAddr
T ialignAddr(T ptr)
Definition: alignPointer.hpp:63
PACK_INT16_TYPE
@ PACK_INT16_TYPE
Definition: packStruct.h:53
FREE_POINTER
#define FREE_POINTER
Definition: packStruct.h:77
PACK_OPR
@ PACK_OPR
Definition: packStruct.h:58
parsePackInstruct
int parsePackInstruct(const char *packInstruct, packItem_t &packItemHead)
Definition: packStruct.cpp:91
NATIVE_PROT
@ NATIVE_PROT
Definition: rodsDef.h:148
irods::pack_entry_table
Definition: irods_pack_table.hpp:13
LOG_DEBUG10
#define LOG_DEBUG10
Definition: rodsLog.h:19
xmlStrToStr
int xmlStrToStr(const char *inStr, int len, char *&outStr)
Definition: packStruct.cpp:1361
packItem::strValue
char strValue[64]
Definition: packStruct.h:85
unpackXmlDoubleToOutPtr
int unpackXmlDoubleToOutPtr(const void *&inPtr, void *&outPtr, int numElement, const char *name)
Definition: packStruct.cpp:2414
packNopackPointer
int packNopackPointer(void *inPtr, packedOutput_t &packedOutput, int len, const char *name, irodsProt_t irodsProt)
Definition: packStruct.cpp:3124
NumOfPackTypes
int NumOfPackTypes
Definition: rodsPackTable.h:31
PACK_DEPENDENT_TYPE
@ PACK_DEPENDENT_TYPE
Definition: packStruct.h:51
strToXmlStr
int strToXmlStr(const char *inStr, char *&outXmlStr)
Definition: packStruct.cpp:1315
size
long long size
Definition: filesystem.cpp:102
packItem::typeInx
packTypeInx_t typeInx
Definition: packStruct.h:80
resolveIntDepItem
int resolveIntDepItem(packItem_t &myPackedItem)
Definition: packStruct.cpp:437
rstrcpy
char * rstrcpy(char *dest, const char *src, int maxLen)
Definition: stringOpr.cpp:51
PACK_STRUCT_TYPE
@ PACK_STRUCT_TYPE
Definition: packStruct.h:50
unpackXmlCharToOutPtr
int unpackXmlCharToOutPtr(const void *&inPtr, void *&outPtr, int len, const char *name, const packTypeInx_t typeInx)
Definition: packStruct.cpp:1842
MAX_PI_LEN
#define MAX_PI_LEN
Definition: packStruct.h:13
NAME_LEN
#define NAME_LEN
Definition: rodsDef.h:55
PACK_BIN_TYPE
@ PACK_BIN_TYPE
Definition: packStruct.h:45
PACKED_OUT_ALLOC_SZ
#define PACKED_OUT_ALLOC_SZ
Definition: packStruct.h:15
packPointerItem
int packPointerItem(packItem_t &myPackedItem, packedOutput_t &packedOutput, const packInstruct_t *myPackTable, int packFlag, irodsProt_t irodsProt)
Definition: packStruct.cpp:870
packItem::intValue
int intValue
Definition: packStruct.h:84
bytesBufArray_t::numBuf
int numBuf
Definition: packStruct.h:96
NO_FREE_POINTER
#define NO_FREE_POINTER
Definition: packStruct.h:73
packItem::pointerType
int pointerType
Definition: packStruct.h:82
alignInt16
T alignInt16(T ptr)
Definition: alignPointer.hpp:43
buf
static char buf[64+50+1]
Definition: rsAuthRequest.cpp:21
paramIn
Definition: ruleAdmin.cpp:32
type
int type
Definition: filesystem.cpp:103
packXmlTag
int packXmlTag(const char *name, packedOutput_t &packedOutput, int flag)
Definition: packStruct.cpp:2960
getNumHintElement
int getNumHintElement(const packItem_t &myPackedItem)
Definition: packStruct.cpp:1090
extendPackedOutput
int extendPackedOutput(packedOutput_t &packedOutput, int extLen, void *&outPtr)
Definition: packStruct.cpp:1099
alignDouble
T alignDouble(T ptr)
Definition: alignPointer.hpp:47