📄 archive.c
字号:
{ unsigned char buf[sizeof (short) + 1]; int len; if ((len = (*stream->read) (stream->physical, (char*)buf, 1))) { if ((buf[0] & _B_CODE) == _B_SINT) (*value) = (buf[0] & _B_VALUE); else { int pos = 1; int nbytes = buf[0] & _B_NUMBER; if (nbytes > (int) sizeof (short)) objc_error (nil, OBJC_ERR_BAD_DATA, "expected short, got bigger (%dbits)", nbytes*8); len = (*stream->read) (stream->physical, (char*)buf + 1, nbytes); (*value) = 0; while (pos <= nbytes) (*value) = ((*value)*0x100) + buf[pos++]; if (buf[0] & _B_SIGN) (*value) = -(*value); } } return len;}inline intobjc_read_unsigned_short (struct objc_typed_stream *stream, unsigned short *value){ unsigned char buf[sizeof (unsigned short) + 1]; int len; if ((len = (*stream->read) (stream->physical, (char*)buf, 1))) { if ((buf[0] & _B_CODE) == _B_SINT) (*value) = (buf[0] & _B_VALUE); else { int pos = 1; int nbytes = buf[0] & _B_NUMBER; if (nbytes > (int) sizeof (short)) objc_error (nil, OBJC_ERR_BAD_DATA, "expected short, got int or bigger"); len = (*stream->read) (stream->physical, (char*)buf + 1, nbytes); (*value) = 0; while (pos <= nbytes) (*value) = ((*value)*0x100) + buf[pos++]; } } return len;}inline intobjc_read_int (struct objc_typed_stream *stream, int *value){ unsigned char buf[sizeof (int) + 1]; int len; if ((len = (*stream->read) (stream->physical, (char*)buf, 1))) { if ((buf[0] & _B_CODE) == _B_SINT) (*value) = (buf[0] & _B_VALUE); else { int pos = 1; int nbytes = buf[0] & _B_NUMBER; if (nbytes > (int) sizeof (int)) objc_error (nil, OBJC_ERR_BAD_DATA, "expected int, got bigger"); len = (*stream->read) (stream->physical, (char*)buf + 1, nbytes); (*value) = 0; while (pos <= nbytes) (*value) = ((*value)*0x100) + buf[pos++]; if (buf[0] & _B_SIGN) (*value) = -(*value); } } return len;}inline intobjc_read_long (struct objc_typed_stream *stream, long *value){ unsigned char buf[sizeof (long) + 1]; int len; if ((len = (*stream->read) (stream->physical, (char*)buf, 1))) { if ((buf[0] & _B_CODE) == _B_SINT) (*value) = (buf[0] & _B_VALUE); else { int pos = 1; int nbytes = buf[0] & _B_NUMBER; if (nbytes > (int) sizeof (long)) objc_error (nil, OBJC_ERR_BAD_DATA, "expected long, got bigger"); len = (*stream->read) (stream->physical, (char*)buf + 1, nbytes); (*value) = 0; while (pos <= nbytes) (*value) = ((*value)*0x100) + buf[pos++]; if (buf[0] & _B_SIGN) (*value) = -(*value); } } return len;}inline int__objc_read_nbyte_uint (struct objc_typed_stream *stream, unsigned int nbytes, unsigned int *val){ int len; unsigned int pos = 0; unsigned char buf[sizeof (unsigned int) + 1]; if (nbytes > sizeof (int)) objc_error (nil, OBJC_ERR_BAD_DATA, "expected int, got bigger"); len = (*stream->read) (stream->physical, (char*)buf, nbytes); (*val) = 0; while (pos < nbytes) (*val) = ((*val)*0x100) + buf[pos++]; return len;} inline intobjc_read_unsigned_int (struct objc_typed_stream *stream, unsigned int *value){ unsigned char buf[sizeof (unsigned int) + 1]; int len; if ((len = (*stream->read) (stream->physical, (char*)buf, 1))) { if ((buf[0] & _B_CODE) == _B_SINT) (*value) = (buf[0] & _B_VALUE); else len = __objc_read_nbyte_uint (stream, (buf[0] & _B_VALUE), value); } return len;}int__objc_read_nbyte_ulong (struct objc_typed_stream *stream, unsigned int nbytes, unsigned long *val){ int len; unsigned int pos = 0; unsigned char buf[sizeof (unsigned long) + 1]; if (nbytes > sizeof (long)) objc_error (nil, OBJC_ERR_BAD_DATA, "expected long, got bigger"); len = (*stream->read) (stream->physical, (char*)buf, nbytes); (*val) = 0; while (pos < nbytes) (*val) = ((*val)*0x100) + buf[pos++]; return len;} inline intobjc_read_unsigned_long (struct objc_typed_stream *stream, unsigned long *value){ unsigned char buf[sizeof (unsigned long) + 1]; int len; if ((len = (*stream->read) (stream->physical, (char*)buf, 1))) { if ((buf[0] & _B_CODE) == _B_SINT) (*value) = (buf[0] & _B_VALUE); else len = __objc_read_nbyte_ulong (stream, (buf[0] & _B_VALUE), value); } return len;}inline intobjc_read_string (struct objc_typed_stream *stream, char **string){ unsigned char buf[sizeof (unsigned int) + 1]; int len; if ((len = (*stream->read) (stream->physical, (char*)buf, 1))) { unsigned long key = 0; if ((buf[0]&_B_CODE) == _B_RCOMM) /* register following */ { len = __objc_read_nbyte_ulong (stream, (buf[0] & _B_VALUE), &key); len = (*stream->read) (stream->physical, (char*)buf, 1); } switch (buf[0]&_B_CODE) { case _B_SSTR: { int length = buf[0]&_B_VALUE; (*string) = (char*)objc_malloc (length + 1); if (key) objc_hash_add (&stream->stream_table, LONG2PTR(key), *string); len = (*stream->read) (stream->physical, *string, length); (*string)[length] = '\0'; } break; case _B_UCOMM: { char *tmp; len = __objc_read_nbyte_ulong (stream, (buf[0] & _B_VALUE), &key); tmp = objc_hash_value_for_key (stream->stream_table, LONG2PTR (key)); *string = objc_malloc (strlen (tmp) + 1); strcpy (*string, tmp); } break; case _B_NSTR: { unsigned int nbytes = buf[0]&_B_VALUE; len = __objc_read_nbyte_uint (stream, nbytes, &nbytes); if (len) { (*string) = (char*)objc_malloc (nbytes + 1); if (key) objc_hash_add (&stream->stream_table, LONG2PTR(key), *string); len = (*stream->read) (stream->physical, *string, nbytes); (*string)[nbytes] = '\0'; } } break; default: objc_error (nil, OBJC_ERR_BAD_DATA, "expected string, got opcode %c\n", (buf[0]&_B_CODE)); } } return len;}intobjc_read_object (struct objc_typed_stream *stream, id *object){ unsigned char buf[sizeof (unsigned int)]; int len; if ((len = (*stream->read) (stream->physical, (char*)buf, 1))) { SEL read_sel = sel_get_any_uid ("read:"); unsigned long key = 0; if ((buf[0]&_B_CODE) == _B_RCOMM) /* register common */ { len = __objc_read_nbyte_ulong (stream, (buf[0] & _B_VALUE), &key); len = (*stream->read) (stream->physical, (char*)buf, 1); } if (buf[0] == (_B_EXT | _BX_OBJECT)) { Class class; /* get class */ len = objc_read_class (stream, &class); /* create instance */ (*object) = class_create_instance (class); /* register? */ if (key) objc_hash_add (&stream->object_table, LONG2PTR(key), *object); /* send -read: */ if (__objc_responds_to (*object, read_sel)) (*get_imp (class, read_sel)) (*object, read_sel, stream); /* check null-byte */ len = (*stream->read) (stream->physical, (char*)buf, 1); if (buf[0] != '\0') objc_error (nil, OBJC_ERR_BAD_DATA, "expected null-byte, got opcode %c", buf[0]); } else if ((buf[0]&_B_CODE) == _B_UCOMM) { if (key) objc_error (nil, OBJC_ERR_BAD_KEY, "cannot register use upcode..."); len = __objc_read_nbyte_ulong (stream, (buf[0] & _B_VALUE), &key); (*object) = objc_hash_value_for_key (stream->object_table, LONG2PTR(key)); } else if (buf[0] == (_B_EXT | _BX_OBJREF)) /* a forward reference */ { struct objc_list *other; len = objc_read_unsigned_long (stream, &key); other = (struct objc_list *) objc_hash_value_for_key (stream->object_refs, LONG2PTR(key)); objc_hash_add (&stream->object_refs, LONG2PTR(key), (void *)list_cons (object, other)); } else if (buf[0] == (_B_EXT | _BX_OBJROOT)) /* a root object */ { if (key) objc_error (nil, OBJC_ERR_BAD_KEY, "cannot register root object..."); len = objc_read_object (stream, object); __objc_finish_read_root_object (stream); } else objc_error (nil, OBJC_ERR_BAD_DATA, "expected object, got opcode %c", buf[0]); } return len;}static intobjc_read_class (struct objc_typed_stream *stream, Class *class){ unsigned char buf[sizeof (unsigned int)]; int len; if ((len = (*stream->read) (stream->physical, (char*)buf, 1))) { unsigned long key = 0; if ((buf[0]&_B_CODE) == _B_RCOMM) /* register following */ { len = __objc_read_nbyte_ulong (stream, (buf[0] & _B_VALUE), &key); len = (*stream->read) (stream->physical, (char*)buf, 1); } if (buf[0] == (_B_EXT | _BX_CLASS)) { char temp[1] = ""; char *class_name = temp; unsigned long version; /* get class */ len = objc_read_string (stream, &class_name); (*class) = objc_get_class (class_name); objc_free (class_name); /* register */ if (key) objc_hash_add (&stream->stream_table, LONG2PTR(key), *class); objc_read_unsigned_long (stream, &version); objc_hash_add (&stream->class_table, (*class)->name, (void *)version); } else if ((buf[0]&_B_CODE) == _B_UCOMM) { if (key) objc_error (nil, OBJC_ERR_BAD_KEY, "cannot register use upcode..."); len = __objc_read_nbyte_ulong (stream, (buf[0] & _B_VALUE), &key); *class = objc_hash_value_for_key (stream->stream_table, LONG2PTR(key)); if (! *class) objc_error (nil, OBJC_ERR_BAD_CLASS, "cannot find class for key %lu", key); } else objc_error (nil, OBJC_ERR_BAD_DATA, "expected class, got opcode %c", buf[0]); } return len;}intobjc_read_selector (struct objc_typed_stream *stream, SEL* selector){ unsigned char buf[sizeof (unsigned int)]; int len; if ((len = (*stream->read) (stream->physical, (char*)buf, 1))) { unsigned long key = 0; if ((buf[0]&_B_CODE) == _B_RCOMM) /* register following */ { len = __objc_read_nbyte_ulong (stream, (buf[0] & _B_VALUE), &key); len = (*stream->read) (stream->physical, (char*)buf, 1); } if (buf[0] == (_B_EXT|_BX_SEL)) /* selector! */ { char temp[1] = ""; char *selector_name = temp; /* get selector */ len = objc_read_string (stream, &selector_name); /* To handle NULL selectors */ if (0 == strlen (selector_name)) { (*selector) = (SEL)0; return 0; } else (*selector) = sel_get_any_uid (selector_name); objc_free (selector_name); /* register */ if (key) objc_hash_add (&stream->stream_table, LONG2PTR(key), (void *) *selector); } else if ((buf[0]&_B_CODE) == _B_UCOMM) { if (key) objc_error (nil, OBJC_ERR_BAD_KEY, "cannot register use upcode..."); len = __objc_read_nbyte_ulong (stream, (buf[0] & _B_VALUE), &key); (*selector) = objc_hash_value_for_key (stream->stream_table, LONG2PTR(key)); } else objc_error (nil, OBJC_ERR_BAD_DATA, "expected selector, got opcode %c", buf[0]); } return len;}/*** USER LEVEL FUNCTIONS*//*** Write one object, encoded in TYPE and pointed to by DATA to the** typed stream STREAM. */intobjc_write_type (TypedStream *stream, const char *type, const void *data){ switch (*type) { case _C_ID: return objc_write_object (stream, *(id *) data); break; case _C_CLASS: return objc_write_class (stream, *(Class *) data); break; case _C_SEL: return objc_write_selector (stream, *(SEL *) data); break; case _C_CHR: return objc_write_char (stream, *(signed char *) data); break; case _C_UCHR: return objc_write_unsigned_char (stream, *(unsigned char *) data); break; case _C_SHT: return objc_write_short (stream, *(short *) data); break; case _C_USHT: return objc_write_unsigned_short (stream, *(unsigned short *) data); break; case _C_INT: return objc_write_int (stream, *(int *) data); break; case _C_UINT: return objc_write_unsigned_int (stream, *(unsigned int *) data); break; case _C_LNG: return objc_write_long (stream, *(long *) data); break; case _C_ULNG: return objc_write_unsigned_long (stream, *(unsigned long *) data); break; case _C_CHARPTR: return objc_write_string (stream, *(unsigned char **) data, strlen (*(char **) data)); break; case _C_ATOM: return objc_write_string_atomic (stream, *(unsigned char **) data, strlen (*(char **) data)); break; case _C_ARY_B: { int len = atoi (type + 1); while (isdigit ((unsigned char) *++type)) ; return objc_write_array (stream, type, len, data); } break; case _C_STRUCT_B: { int acc_size = 0; int align; while (*type != _C_STRUCT_E && *type++ != '=') ; /* skip "<name>=" */ while (*type != _C_STRUCT_E) { align = objc_alignof_type (type); /* padd to alignment */ acc_size = ROUND (acc_size, align); objc_write_type (stream, type, ((char *) data) + acc_size); acc_size += objc_sizeof_type (type); /* add component size */ type = objc_skip_typespec (type); /* skip component */ } return 1; } default: { objc_error (nil, OBJC_ERR_BAD_TYPE, "objc_write_type: cannot parse typespec: %s\n", type); return 0; } }}/*** Read one object, encoded in TYPE and pointed to by DATA to the** typed stream STREAM. DATA specifies the address of the types to** read. Expected type is checked against the type actually present** on the stream. */intobjc_read_type(TypedStream *stream, const char *type, void *data){ char c; switch (c = *type) { case _C_ID: return objc_read_object (stream, (id*)data); break; case _C_CLASS: return objc_read_class (stream, (Class*)data); break; case _C_SEL: return objc_read_selector (stream, (SEL*)data); break; case _C_CHR: return objc_read_char (stream, (char*)data);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -