~ubuntu-branches/ubuntu/trusty/gnustep-base/trusty

« back to all changes in this revision

Viewing changes to Source/NSUnarchiver.m

Tags: upstream-1.20.0
ImportĀ upstreamĀ versionĀ 1.20.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
   Boston, MA 02111 USA.
23
23
 
24
24
   <title>NSUnarchiver class reference</title>
25
 
   $Date: 2008-12-08 09:08:05 +0000 (Mon, 08 Dec 2008) $ $Revision: 27257 $
 
25
   $Date: 2010-03-09 03:09:01 -0700 (Tue, 09 Mar 2010) $ $Revision: 29887 $
26
26
   */
27
27
 
28
 
#import "config.h"
 
28
#import "common.h"
 
29
#define EXPOSE_NSUnarchiver_IVARS       1
29
30
#include <string.h>
30
 
#import "Foundation/NSObjCRuntime.h"
31
31
#import "Foundation/NSDictionary.h"
32
 
#import "Foundation/NSZone.h"
33
32
#import "Foundation/NSException.h"
34
33
#import "Foundation/NSByteOrder.h"
35
34
 
43
42
#include "GNUstepBase/GSIArray.h"
44
43
 
45
44
#define _IN_NSUNARCHIVER_M
46
 
#include "Foundation/NSArchiver.h"
 
45
#import "Foundation/NSArchiver.h"
47
46
#undef  _IN_NSUNARCHIVER_M
48
47
 
49
 
#include "Foundation/NSAutoreleasePool.h"
50
 
#include "Foundation/NSCoder.h"
51
 
#include "Foundation/NSData.h"
52
 
#include "Foundation/NSString.h"
53
 
#include "Foundation/NSArray.h"
 
48
#import "Foundation/NSAutoreleasePool.h"
 
49
#import "Foundation/NSCoder.h"
 
50
#import "Foundation/NSData.h"
 
51
#import "Foundation/NSArray.h"
54
52
 
55
53
@class NSDataMalloc;
56
54
@interface NSDataMalloc : NSObject      // Help the compiler
160
158
  _C_UINT,
161
159
  _C_LNG,
162
160
  _C_ULNG,
163
 
#ifdef  _C_LNG_LNG
164
161
  _C_LNG_LNG,
165
162
  _C_ULNG_LNG,
166
 
#else
167
 
  0,
168
 
  0,
169
 
#endif
170
163
  _C_FLT,
171
164
  _C_DBL,
172
165
  0,
190
183
  0
191
184
};
192
185
 
193
 
static inline void
 
186
 
 
187
static inline BOOL
194
188
typeCheck(char t1, char t2)
195
189
{
196
190
  if (type_map[(t2 & _GSC_MASK)] != t1)
202
196
 * can vary.
203
197
 */
204
198
      char      c = type_map[(t2 & _GSC_MASK)];
205
 
      if ((c == _C_INT || c == _C_LNG
206
 
#ifdef  _C_LNG_LNG
207
 
        || c == _C_LNG_LNG
208
 
#endif
209
 
        ) && (t1 == _C_INT || t1 == _C_LNG
210
 
#ifdef  _C_LNG_LNG
211
 
        || t1 == _C_LNG_LNG
212
 
#endif
213
 
        )) return;
214
 
      if ((c == _C_UINT || c == _C_ULNG
215
 
#ifdef  _C_LNG_LNG
216
 
        || c == _C_ULNG_LNG
217
 
#endif
218
 
        ) && (t1 == _C_UINT || t1 == _C_ULNG
219
 
#ifdef  _C_LNG_LNG
220
 
        || t1 == _C_ULNG_LNG
221
 
#endif
222
 
        )) return;
 
199
      char      s1;
 
200
      char      s2;
 
201
 
 
202
      switch (t1)
 
203
        {
 
204
          case _C_SHT:  s1 = _GSC_S_SHT; break;
 
205
          case _C_USHT:  s1 = _GSC_S_SHT; break;
 
206
          case _C_INT:  s1 = _GSC_S_INT; break;
 
207
          case _C_UINT:  s1 = _GSC_S_INT; break;
 
208
          case _C_LNG:  s1 = _GSC_S_LNG; break;
 
209
          case _C_ULNG:  s1 = _GSC_S_LNG; break;
 
210
          case _C_LNG_LNG:  s1 = _GSC_S_LNG_LNG; break;
 
211
          case _C_ULNG_LNG:  s1 = _GSC_S_LNG_LNG; break;
 
212
          default:      s1 = 0;
 
213
        }
 
214
 
 
215
      switch (t2)
 
216
        {
 
217
          case _C_SHT:  s2 = _GSC_S_SHT; break;
 
218
          case _C_USHT:  s2 = _GSC_S_SHT; break;
 
219
          case _C_INT:  s2 = _GSC_S_INT; break;
 
220
          case _C_UINT:  s2 = _GSC_S_INT; break;
 
221
          case _C_LNG:  s2 = _GSC_S_LNG; break;
 
222
          case _C_ULNG:  s2 = _GSC_S_LNG; break;
 
223
          case _C_LNG_LNG:  s2 = _GSC_S_LNG_LNG; break;
 
224
          case _C_ULNG_LNG:  s2 = _GSC_S_LNG_LNG; break;
 
225
          default:      s2 = 0;
 
226
        }
 
227
 
 
228
      if ((c == _C_INT || c == _C_LNG || c == _C_LNG_LNG)
 
229
        && (t1 == _C_INT || t1 == _C_LNG || t1 == _C_LNG_LNG))
 
230
        return s1 == s2 ? YES : NO;
 
231
 
 
232
      if ((c == _C_UINT || c == _C_ULNG || c == _C_ULNG_LNG)
 
233
        && (t1 == _C_UINT || t1 == _C_ULNG || t1 == _C_ULNG_LNG))
 
234
        return s1 == s2 ? YES : NO;
 
235
 
 
236
/* HACK also allow float and double to be used interchangably as MacOS-X
 
237
 * intorduced CGFloat, which may be aither a float or a double.
 
238
 */
 
239
      if ((c == _C_FLT || c == _C_DBL) && (t1 == _C_FLT || t1 == _C_DBL))
 
240
        return NO;
223
241
 
224
242
      [NSException raise: NSInternalInconsistencyException
225
243
                  format: @"expected %s and got %s",
226
244
                    typeToName1(t1), typeToName2(t2)];
227
245
    }
 
246
  return YES;
228
247
}
229
248
 
230
249
#define PREFIX          "GNUstep archive"
493
512
        }
494
513
      NS_HANDLER
495
514
        {
496
 
          RELEASE(self);
 
515
          DESTROY(self);
497
516
          [localException raise];
498
517
        }
499
518
      NS_ENDHANDLER
536
555
      case _C_UINT:     info = _GSC_UINT; break;
537
556
      case _C_LNG:      info = _GSC_LNG; break;
538
557
      case _C_ULNG:     info = _GSC_ULNG; break;
539
 
#ifdef  _C_LNG_LNG
540
558
      case _C_LNG_LNG:  info = _GSC_LNG_LNG; break;
541
559
      case _C_ULNG_LNG: info = _GSC_ULNG_LNG; break;
542
 
#endif
543
560
      case _C_FLT:      info = _GSC_FLT; break;
544
561
      case _C_DBL:      info = _GSC_DBL; break;
545
562
      default:          info = _GSC_NONE; break;
581
598
{
582
599
  unsigned      xref;
583
600
  unsigned char info;
584
 
#if     GS_HAVE_I128
585
 
    gsu128      bigval;
586
 
#else
587
 
#if     GS_HAVE_I64
588
 
    uint64_t    bigval;
589
 
#else
590
 
    uint32_t    bigval;
591
 
#endif
592
 
#endif
593
601
 
594
602
  (*tagImp)(src, tagSel, &info, &xref, &cursor);
595
603
 
741
749
              if (className == 0)
742
750
                {
743
751
                  NSLog(@"[%s %s] decoded nil class name",
744
 
                    GSNameFromClass([self class]), GSNameFromSelector(_cmd));
 
752
                    class_getName([self class]), sel_getName(_cmd));
745
753
                  className = @"_NSUnarchiverUnknownClass";
746
754
                }
747
755
              classInfo = [objDict objectForKey: className];
756
764
                   */
757
765
                  if (c == nil)
758
766
                    {
759
 
                      NSLog(@"Got nil when trying to unarchive class %s",
760
 
                        className);
 
767
                      NSLog(@"Unable to find class named '%@'", className);
761
768
                    }
762
769
                  [classInfo mapToClass: c withName: className];
763
770
                  [objDict setObject: classInfo forKey: className];
949
956
 
950
957
      case _GSC_SHT:
951
958
      case _GSC_USHT:
952
 
        typeCheck(*type, info & _GSC_MASK);
953
 
        if ((info & _GSC_SIZE) == _GSC_S_SHT)
 
959
        if (YES == typeCheck(*type, info & _GSC_MASK)
 
960
          && (info & _GSC_SIZE) == _GSC_S_SHT)
954
961
          {
955
962
            (*desImp)(src, desSel, address, type, &cursor, nil);
956
963
            return;
959
966
 
960
967
      case _GSC_INT:
961
968
      case _GSC_UINT:
962
 
        typeCheck(*type, info & _GSC_MASK);
963
 
        if ((info & _GSC_SIZE) == _GSC_S_INT)
 
969
        if (YES == typeCheck(*type, info & _GSC_MASK)
 
970
          &&  (info & _GSC_SIZE) == _GSC_S_INT)
964
971
          {
965
972
            (*desImp)(src, desSel, address, type, &cursor, nil);
966
973
            return;
969
976
 
970
977
      case _GSC_LNG:
971
978
      case _GSC_ULNG:
972
 
        typeCheck(*type, info & _GSC_MASK);
973
 
        if ((info & _GSC_SIZE) == _GSC_S_LNG)
 
979
        if (YES == typeCheck(*type, info & _GSC_MASK)
 
980
          && (info & _GSC_SIZE) == _GSC_S_LNG)
974
981
          {
975
982
            (*desImp)(src, desSel, address, type, &cursor, nil);
976
983
            return;
977
984
          }
978
985
        break;
979
986
 
980
 
#ifdef  _C_LNG_LNG
981
987
      case _GSC_LNG_LNG:
982
988
      case _GSC_ULNG_LNG:
983
 
        typeCheck(*type, info & _GSC_MASK);
984
 
        if ((info & _GSC_SIZE) == _GSC_S_LNG_LNG)
 
989
        if (YES == typeCheck(*type, info & _GSC_MASK)
 
990
          && (info & _GSC_SIZE) == _GSC_S_LNG_LNG)
985
991
          {
986
992
            (*desImp)(src, desSel, address, type, &cursor, nil);
987
993
            return;
988
994
          }
989
995
        break;
990
996
 
991
 
#endif
992
997
      case _GSC_FLT:
993
 
        typeCheck(*type, _GSC_FLT);
994
 
        (*desImp)(src, desSel, address, type, &cursor, nil);
 
998
        if (YES == typeCheck(*type, _GSC_FLT)
 
999
          && *type == _C_FLT)
 
1000
          {
 
1001
            (*desImp)(src, desSel, address, type, &cursor, nil);
 
1002
          }
 
1003
        else
 
1004
          {
 
1005
            float       val;
 
1006
 
 
1007
            /* We found a float when expecting a double ... handle it.
 
1008
             */
 
1009
            (*desImp)(src, desSel, &val, @encode(float), &cursor, nil);
 
1010
            *(double*)address = (double)val;
 
1011
          }
995
1012
        return;
996
1013
 
997
1014
      case _GSC_DBL:
998
 
        typeCheck(*type, _GSC_DBL);
999
 
        (*desImp)(src, desSel, address, type, &cursor, nil);
 
1015
        if (YES == typeCheck(*type, _GSC_DBL)
 
1016
          && *type == _C_DBL)
 
1017
          {
 
1018
            (*desImp)(src, desSel, address, type, &cursor, nil);
 
1019
          }
 
1020
        else
 
1021
          {
 
1022
            double      val;
 
1023
 
 
1024
            /* We found a double when expecting a float ... handle it.
 
1025
             */
 
1026
            (*desImp)(src, desSel, &val, @encode(double), &cursor, nil);
 
1027
            *(float*)address = (float)val;
 
1028
          }
1000
1029
        return;
1001
1030
 
1002
1031
      default:
1004
1033
                    format: @"read unknown type info - %d", info];
1005
1034
    }
1006
1035
 
 
1036
{
 
1037
  uint8_t       size;
 
1038
 
1007
1039
  /*
1008
1040
   *    We fall through to here only when we have to decode a value
1009
1041
   *    whose natural size on this system is not the same as on the
1010
1042
   *    machine on which the archive was created.
1011
1043
   */
1012
1044
 
 
1045
  switch (*type)
 
1046
    {
 
1047
      case _C_SHT:
 
1048
      case _C_USHT:  size = sizeof(short); break;
 
1049
      case _C_INT: 
 
1050
      case _C_UINT:  size = sizeof(int); break;
 
1051
      case _C_LNG:
 
1052
      case _C_ULNG:  size = sizeof(long); break;
 
1053
      case _C_LNG_LNG:
 
1054
      case _C_ULNG_LNG:  size = sizeof(long long); break;
 
1055
      default:      size = 1;
 
1056
    }
 
1057
 
1013
1058
  /*
1014
1059
   *    First, we read the data and convert it to the largest size
1015
1060
   *    this system can support.
1016
1061
   */
1017
 
  switch (info & _GSC_SIZE)
1018
 
    {
1019
 
      case _GSC_I16:    /* Encoded as 16-bit    */
1020
 
        {
1021
 
          uint16_t      val;
1022
 
 
1023
 
          (*desImp)(src, desSel, &val, @encode(uint16_t), &cursor, nil);
1024
 
          bigval = val;
1025
 
          break;
1026
 
        }
1027
 
 
1028
 
      case _GSC_I32:    /* Encoded as 32-bit    */
1029
 
        {
1030
 
          uint32_t      val;
1031
 
 
1032
 
          (*desImp)(src, desSel, &val, @encode(uint32_t), &cursor, nil);
1033
 
          bigval = val;
1034
 
          break;
1035
 
        }
1036
 
 
1037
 
      case _GSC_I64:    /* Encoded as 64-bit    */
1038
 
        {
1039
 
          uint64_t      val;
1040
 
 
1041
 
          (*desImp)(src, desSel, &val, @encode(uint64_t), &cursor, nil);
1042
 
#if     GS_HAVE_I64
1043
 
          bigval = val;
1044
 
#else
1045
 
          bigval = GSSwapBigI64ToHost(val);
1046
 
#endif
1047
 
          break;
1048
 
        }
1049
 
 
1050
 
      default:          /* A 128-bit value      */
1051
 
        {
1052
 
          gsu128        val;
1053
 
 
1054
 
          (*desImp)(src, desSel, &val, @encode(gsu128), &cursor, nil);
1055
 
#if     GS_HAVE_I128
1056
 
          bigval = val;
1057
 
#else
1058
 
          val = GSSwapBigI128ToHost(val);
1059
 
#if     GS_HAVE_I64
1060
 
          bigval = *(uint64_t*)&val;
1061
 
#else
1062
 
          bigval = *(uint32_t*)&val;
1063
 
#endif
1064
 
#endif
1065
 
          break;
1066
 
        }
1067
 
    }
1068
 
 
1069
 
/*
1070
 
 *      Now we copy from the 'bigval' to the destination location.
1071
 
 */
1072
 
  switch (info & _GSC_MASK)
1073
 
    {
1074
 
      case _GSC_SHT:
1075
 
        *(short*)address = (short)bigval;
1076
 
        return;
1077
 
      case _GSC_USHT:
1078
 
        *(unsigned short*)address = (unsigned short)bigval;
1079
 
        return;
1080
 
      case _GSC_INT:
1081
 
        *(int*)address = (int)bigval;
1082
 
        return;
1083
 
      case _GSC_UINT:
1084
 
        *(unsigned int*)address = (unsigned int)bigval;
1085
 
        return;
1086
 
      case _GSC_LNG:
1087
 
        *(long*)address = (long)bigval;
1088
 
        return;
1089
 
      case _GSC_ULNG:
1090
 
        *(unsigned long*)address = (unsigned long)bigval;
1091
 
        return;
1092
 
#ifdef  _C_LNG_LNG
1093
 
      case _GSC_LNG_LNG:
1094
 
        *(long long*)address = (long long)bigval;
1095
 
        return;
1096
 
      case _GSC_ULNG_LNG:
1097
 
        *(unsigned long long*)address = (unsigned long long)bigval;
1098
 
        return;
1099
 
#endif
1100
 
      default:
1101
 
        [NSException raise: NSInternalInconsistencyException
1102
 
                    format: @"type/size information error"];
1103
 
    }
 
1062
  if (*type == _C_SHT
 
1063
    || *type == _C_INT
 
1064
    || *type == _C_LNG
 
1065
    || *type == _C_LNG_LNG)
 
1066
    {
 
1067
      int64_t   big;
 
1068
 
 
1069
      switch (info & _GSC_SIZE)
 
1070
        {
 
1071
          case _GSC_I16:        /* Encoded as 16-bit    */
 
1072
            {
 
1073
              int16_t   val;
 
1074
 
 
1075
              (*desImp)(src, desSel, &val, @encode(int16_t), &cursor, nil);
 
1076
              big = val;
 
1077
              break;
 
1078
            }
 
1079
 
 
1080
          case _GSC_I32:        /* Encoded as 32-bit    */
 
1081
            {
 
1082
              int32_t   val;
 
1083
 
 
1084
              (*desImp)(src, desSel, &val, @encode(int32_t), &cursor, nil);
 
1085
              big = val;
 
1086
              break;
 
1087
            }
 
1088
 
 
1089
          case _GSC_I64:        /* Encoded as 64-bit    */
 
1090
            {
 
1091
              (*desImp)(src, desSel, &big, @encode(int64_t), &cursor, nil);
 
1092
              break;
 
1093
            }
 
1094
 
 
1095
          default:              /* A 128-bit value      */
 
1096
            {
 
1097
              big = 0;
 
1098
              [NSException raise: NSInternalInconsistencyException
 
1099
                          format: @"Archiving of 128bit integer not allowed"];
 
1100
            }
 
1101
        }
 
1102
      /*
 
1103
       *        Now we copy from the big value to the destination location.
 
1104
       */
 
1105
      switch (size)
 
1106
        {
 
1107
          case 1:
 
1108
            *(int8_t*)address = (int8_t)big;
 
1109
            if (big & ~0xff)
 
1110
              {
 
1111
                if ((int8_t)big >= 0 || (big & ~0xff) != ~0xff)
 
1112
                  {
 
1113
                    NSLog(@"Loss of information converting decoded value to int8_t");
 
1114
                  }
 
1115
              }
 
1116
            return;
 
1117
          case 2:
 
1118
            *(int16_t*)address = (int16_t)big;
 
1119
            if (big & ~0xffff)
 
1120
              {
 
1121
                if ((int16_t)big >= 0 || (big & ~0xffff) != ~0xffff)
 
1122
                  {
 
1123
                    NSLog(@"Loss of information converting decoded value to int16_t");
 
1124
                  }
 
1125
              }
 
1126
            return;
 
1127
          case 4:
 
1128
            *(int32_t*)address = (int32_t)big;
 
1129
            if (big & ~0xffffffff)
 
1130
              {
 
1131
                if ((int32_t)big >= 0 || (big & ~0xffffffff) != ~0xffffffff)
 
1132
                  {
 
1133
                    NSLog(@"Loss of information converting decoded value to int32_t");
 
1134
                  }
 
1135
              }
 
1136
            return;
 
1137
          case 8:
 
1138
            *(int64_t*)address = big;
 
1139
            return;
 
1140
          default:
 
1141
            [NSException raise: NSInternalInconsistencyException
 
1142
                        format: @"type/size information error"];
 
1143
        }
 
1144
    }
 
1145
  else
 
1146
    {
 
1147
      uint64_t  big;
 
1148
 
 
1149
      switch (info & _GSC_SIZE)
 
1150
        {
 
1151
          case _GSC_I16:        /* Encoded as 16-bit    */
 
1152
            {
 
1153
              uint16_t  val;
 
1154
 
 
1155
              (*desImp)(src, desSel, &val, @encode(uint16_t), &cursor, nil);
 
1156
              big = val;
 
1157
              break;
 
1158
            }
 
1159
 
 
1160
          case _GSC_I32:        /* Encoded as 32-bit    */
 
1161
            {
 
1162
              uint32_t  val;
 
1163
 
 
1164
              (*desImp)(src, desSel, &val, @encode(uint32_t), &cursor, nil);
 
1165
              big = val;
 
1166
              break;
 
1167
            }
 
1168
 
 
1169
          case _GSC_I64:        /* Encoded as 64-bit    */
 
1170
            {
 
1171
              (*desImp)(src, desSel, &big, @encode(uint64_t), &cursor, nil);
 
1172
              break;
 
1173
            }
 
1174
 
 
1175
          default:              /* A 128-bit value      */
 
1176
            {
 
1177
              big = 0;
 
1178
              [NSException raise: NSInternalInconsistencyException
 
1179
                          format: @"Archiving of 128bit integer not allowed"];
 
1180
            }
 
1181
        }
 
1182
      /*
 
1183
       * Now we copy from the big value to the destination location.
 
1184
       */
 
1185
      switch (size)
 
1186
        {
 
1187
          case 1:
 
1188
            if (big & ~0xff)
 
1189
              {
 
1190
                NSLog(@"Loss of information converting decoded value to uint8_t");
 
1191
              }
 
1192
            *(uint8_t*)address = (uint8_t)big;
 
1193
            return;
 
1194
          case 2:
 
1195
            if (big & ~0xffff)
 
1196
              {
 
1197
                NSLog(@"Loss of information converting decoded value to uint16_t");
 
1198
              }
 
1199
            *(uint8_t*)address = (uint8_t)big;
 
1200
            *(uint16_t*)address = (uint16_t)big;
 
1201
            return;
 
1202
          case 4:
 
1203
            if (big & ~0xffffffff)
 
1204
              {
 
1205
                NSLog(@"Loss of information converting decoded value to uint32_t");
 
1206
              }
 
1207
            *(uint32_t*)address = (uint32_t)big;
 
1208
            return;
 
1209
          case 8:
 
1210
            *(uint64_t*)address = big;
 
1211
            return;
 
1212
          default:
 
1213
            [NSException raise: NSInternalInconsistencyException
 
1214
                        format: @"type/size information error"];
 
1215
        }
 
1216
    }
 
1217
}
1104
1218
}
1105
1219
 
1106
1220
- (NSData*) decodeDataObject
1117
1231
        {
1118
1232
          void          *b;
1119
1233
          NSData        *d;
1120
 
          NSZone        *z;
1121
1234
 
1122
1235
#if     GS_WITH_GC
1123
 
          z = GSAtomicMallocZone();
 
1236
          b = NSAllocateCollectable(l, 0);
1124
1237
#else
1125
 
          z = zone;
 
1238
          b = NSZoneMalloc(zone, l);
1126
1239
#endif
1127
 
          b = NSZoneMalloc(z, l);
1128
1240
          [self decodeArrayOfObjCType: @encode(unsigned char)
1129
1241
                                count: l
1130
1242
                                   at: b];
1206
1318
{
1207
1319
  Class c;
1208
1320
 
1209
 
  c = GSClassFromName([trueName cString]);
 
1321
  c = objc_lookUpClass([trueName cString]);
1210
1322
  if (c == 0)
1211
1323
    {
1212
1324
      [NSException raise: NSInvalidArgumentException
1258
1370
{
1259
1371
  Class c;
1260
1372
 
1261
 
  c = GSClassFromName([trueName cString]);
 
1373
  c = objc_lookUpClass([trueName cString]);
1262
1374
  if (c == 0)
1263
1375
    {
1264
1376
      [NSException raise: NSInvalidArgumentException
1353
1465
 
1354
1466
      TEST_RELEASE(data);
1355
1467
      data = RETAIN(anObject);
1356
 
      c = GSObjCClass(data);
 
1468
      c = object_getClass(data);
1357
1469
      if (src != self)
1358
1470
        {
1359
1471
          src = data;