Changeset 90
- Timestamp:
- 03/27/07 06:22:21 (5 years ago)
- Location:
- NEWT0/trunk/src/newt_core
- Files:
-
- 3 edited
-
NewtPkg.c (modified) (8 diffs)
-
incs/NewtType.h (modified) (1 diff)
-
incs/VC6/NewtConf.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
NEWT0/trunk/src/newt_core/NewtPkg.c
r89 r90 11 11 12 12 13 /* ヘッダファイル includes */13 /* header files */ 14 14 #include <string.h> 15 15 … … 17 17 #include "NewtErrs.h" 18 18 #include "NewtObj.h" 19 //#include "NewtEnv.h"20 //#include "NewtFns.h"21 //#include "NewtVM.h"22 //#include "NewtIconv.h"19 #include "NewtEnv.h" 20 #include "NewtFns.h" 21 #include "NewtVM.h" 22 #include "NewtIconv.h" 23 23 24 24 #include "utils/endian_utils.h" 25 25 26 27 /* マクロ defines */ 26 #undef DEBUG_PKG_DIS 27 #define DEBUG_PKG 28 #ifdef DEBUG_PKG 29 # include "NewtPrint.h" 30 #endif 31 32 /* macros */ 28 33 29 34 /// Test first 8 bytes for package signature 30 #define PkgIsPackage(data) ((strncmp(data, "package0", 8)==0) || (strncmp(data, "package 0", 8)==0))31 32 33 /* 型宣言types */35 #define PkgIsPackage(data) ((strncmp(data, "package0", 8)==0) || (strncmp(data, "package1", 8)==0)) 36 37 38 /* types */ 34 39 35 40 /// info refs are a shorthand version of pointers into a userdata area of the package … … 48 53 pkg_info_ref_t name; ///< utf16 package name 49 54 uint32_t size; ///< entire size of package 50 uint32_t dat a; ///< creation data55 uint32_t date; ///< creation date 51 56 uint32_t reserverd2; 52 57 uint32_t reserverd3; … … 72 77 uint8_t * data; ///< package data 73 78 uint32_t size; ///< size of package 74 pkg_header_t *header; ///< pointer to the package header 75 pkg_part_t *part_headers; ///< pointer to first part header - can be used as an array 79 pkg_header_t * header; ///< pointer to the package header 80 uint8_t * var_len_data; ///< extra data for header 81 uint32_t num_parts; ///< number of parts in package 82 pkg_part_t* part_headers; ///< pointer to first part header - can be used as an array 83 pkg_part_t* part_header; ///< header of current part 84 uint8_t * part; ///< start of current part data 76 85 newtErr lastErr; ///< a way to return error from deep below 86 #ifdef HAVE_LIBICONV 87 iconv_t from_utf16; ///< strings in compatible packages are UTF16 88 #endif /* HAVE_LIBICONV */ 77 89 } pkg_stream_t; 78 90 79 91 80 /* 関数プロトタイプ functions */ 92 /* functions */ 93 uint32_t PkgReadU32(uint8_t *d); 94 95 newtRef PkgReadRef(pkg_stream_t *pkg, uint32_t p_obj); 96 newtRef PkgReadBinaryObject(pkg_stream_t *pkg, uint32_t p_obj); 97 newtRef PkgReadArrayObject(pkg_stream_t *pkg, uint32_t p_obj); 98 newtRef PkgReadFrameObject(pkg_stream_t *pkg, uint32_t p_obj); 99 newtRef PkgReadObject(pkg_stream_t *pkg, uint32_t p_obj); 100 81 101 newtRef PkgReadPart(pkg_stream_t *pkg, int32_t index); 102 103 newtRef PkgReadVardataString(pkg_stream_t *pkg, pkg_info_ref_t *info_ref); 104 newtRef PkgReadVardataBinary(pkg_stream_t *pkg, pkg_info_ref_t *info_ref); 105 newtRef PkgReadHeader(pkg_stream_t *pkg); 106 82 107 newtRef NewtReadPkg(uint8_t * data, size_t size); 83 108 84 109 /*------------------------------------------------------------------------*/ 110 /** Endian-neutral conversion of four bytes into one uint32 111 * 112 * @param d [in] pointer to byte array 113 * 114 * @retval uint32 assembled from four bytes 115 */ 116 uint32_t PkgReadU32(uint8_t *d) 117 { 118 return ((d[0]<<24)|(d[1]<<16)|(d[2]<<8)|(d[3])); 119 } 120 121 /*------------------------------------------------------------------------*/ 122 /** Generate a ref from package data 123 * 124 * @param pkg [inout] the package 125 * @param p_obj [in] offset to Ref data relative to package start 126 * 127 * @retval Newt object version of package Ref 128 */ 129 newtRef PkgReadRef(pkg_stream_t *pkg, uint32_t p_obj) 130 { 131 uint32_t ref = PkgReadU32(pkg->data + p_obj); 132 newtRef result = kNewtRefNIL; 133 134 switch (ref&3) { 135 case 0: // integer 136 result = NSINT(ref>>2); 137 break; 138 case 1: // pointer 139 result = PkgReadObject(pkg, ref&~3); 140 break; 141 case 2: // special 142 if (ref==kNewtRefTRUE) result = kNewtRefTRUE; 143 else if (ref==kNewtRefNIL) result = kNewtRefNIL; 144 else if (ref&0x0f==0x0a) result = NewtMakeCharacter(ref>>4); 145 else if (ref==kNewtSymbolClass) result = kNewtSymbolClass; 146 else if (ref==0x32) { 147 result = 0x32; 148 printf("*** PkgReader: PkgReadRef - unsupported ref 0x%08x - what is this?\n", ref); 149 } else { 150 # ifdef DEBUG_PKG 151 printf("*** PkgReader: PkgReadRef - unsupported ref 0x%08x\n", ref); 152 # endif 153 result = ref; 154 } 155 break; 156 case 3: // magic pointer 157 # ifdef __NAMED_MAGIC_POINTER__ 158 result = kNewtRefNIL; // no timplemented 159 # else 160 result = ref; // already a correct magic pointer 161 # endif 162 break; 163 } 164 165 return result; 166 } 167 168 /*------------------------------------------------------------------------*/ 169 /** Generate a binary object from package data 170 * 171 * @param pkg [inout] the package 172 * @param p_obj [in] offset to binary data object relative to package start 173 * 174 * @retval Newt object version of binary object 175 */ 176 newtRef PkgReadBinaryObject(pkg_stream_t *pkg, uint32_t p_obj) 177 { 178 uint32_t size = PkgReadU32(pkg->data + p_obj) >> 8; 179 newtRef klass, result = kNewtRefNIL; 180 newtRef ins = NSSYM0(instructions); 181 182 klass = PkgReadRef(pkg, p_obj+8); 183 184 if (klass==kNewtSymbolClass) { 185 result = NewtMakeSymbol(pkg->data + p_obj + 16); 186 } else if (klass==NSSYM0(string)) { 187 char *src = pkg->data + p_obj + 12; 188 int sze = size-12; 189 # ifdef HAVE_LIBICONV 190 size_t buflen; 191 char *buf = NewtIconv(pkg->from_utf16, src, sze, &buflen); 192 if (buf) { 193 result = NewtMakeString2(buf, buflen, false); 194 } 195 # endif /* HAVE_LIBICONV */ 196 if (result==kNewtRefNIL) 197 result = NewtMakeString2(src, sze, false); 198 } else if (klass==NSSYM0(int32)) { 199 uint32_t v = PkgReadU32(pkg->data + p_obj + 12); 200 result = NewtMakeInt32(v); 201 } else if (klass==NSSYM0(real)) { 202 double *v = (double*)(pkg->data + p_obj + 12); 203 result = NewtMakeReal(ntohd(*v)); 204 } else if (klass==NSSYM0(instructions)) { 205 result = NewtMakeBinary(klass, pkg->data + p_obj + 12, size-12, false); 206 # ifdef DEBUG_PKG_DIS 207 printf("*** PkgReader: PkgReadBinaryObject - dumping byte code\n"); 208 NVMDumpBC(stdout, result); 209 # endif 210 } else { 211 // bits: the bits in the icon 212 // mask: the transparency mask for the icon 213 # ifdef DEBUG_PKG 214 if (klass) { 215 printf("*** PkgReader: PkgReadBinaryObject - unknown class "); 216 NewtPrintObject(stdout, klass); 217 } 218 # endif 219 result = NewtMakeBinary(klass, pkg->data + p_obj + 12, size-12, false); 220 } 221 222 return result; 223 } 224 225 /*------------------------------------------------------------------------*/ 226 /** Generate an array from package data 227 * 228 * @param pkg [inout] the package 229 * @param p_obj [in] offset to array data relative to package start 230 * 231 * @retval Newt object version of package Array 232 */ 233 newtRef PkgReadArrayObject(pkg_stream_t *pkg, uint32_t p_obj) 234 { 235 uint32_t size = PkgReadU32(pkg->data + p_obj) >> 8; 236 uint32_t num_slots = size/4 - 3; 237 uint32_t i; 238 newtRef array, klass; 239 240 klass = PkgReadRef(pkg, p_obj+8); 241 array = NewtMakeArray(klass, num_slots); 242 243 if (NewtRefIsNotNIL(array)) { 244 for (i=0; i<num_slots; i++) { 245 NewtSetArraySlot(array, i, PkgReadRef(pkg, p_obj+12 + 4*i)); 246 } 247 } 248 249 return array; 250 } 251 252 253 /*------------------------------------------------------------------------*/ 254 /** Generate a frame from package data 255 * 256 * @param pkg [inout] the package 257 * @param p_obj [in] offset to frame data relative to package start 258 * 259 * @retval Newt object version of package Frame 260 */ 261 newtRef PkgReadFrameObject(pkg_stream_t *pkg, uint32_t p_obj) 262 { 263 uint32_t size = PkgReadU32(pkg->data + p_obj) >> 8; 264 uint32_t i, num_slots = size/4 - 3; 265 newtRef frame = kNewtRefNIL, map; 266 267 map = PkgReadRef(pkg, p_obj+8); 268 269 frame = NewtMakeFrame(map, num_slots); 270 271 if (NewtRefIsNotNIL(frame)) { 272 273 newtRef *slot = NewtRefToSlots(frame); 274 for (i=0; i<num_slots; i++) { 275 slot[i] = PkgReadRef(pkg, p_obj+12 + 4*i); 276 } 277 } 278 279 return frame; 280 } 281 282 /*------------------------------------------------------------------------*/ 283 /** Recursively read the object at the given offset 284 * 285 * @param pkg [inout] the package 286 * @param p_obj [in] offset to object relative to package start 287 * 288 * @retval Newt object version of package object 289 */ 290 newtRef PkgReadObject(pkg_stream_t *pkg, uint32_t p_obj) 291 { 292 uint32_t obj = PkgReadU32(pkg->data + p_obj); 293 newtRef ret = kNewtRefNIL; 294 295 switch (obj & 0xff) { 296 case 0x40: // binary object 297 ret = PkgReadBinaryObject(pkg, p_obj); 298 break; 299 case 0x40 | kObjSlotted: // array 300 ret = PkgReadArrayObject(pkg, p_obj); 301 break; 302 case 0x40 | kObjSlotted | kObjFrame: // frame 303 ret = PkgReadFrameObject(pkg, p_obj); 304 break; 305 case 0x40 | kObjFrame: // not defined 306 default: 307 # ifdef DEBUG_PKG 308 printf("*** PkgReader: PkgReadObject - unsupported object 0x%08x\n", obj); 309 # endif 310 break; 311 } 312 return ret; 313 } 314 315 /*------------------------------------------------------------------------*/ 316 /** Read a NOS part from the package file. 317 * 318 * @param pkg [inout] the package 319 * 320 * @retval Newt object with contents of NOS part 321 */ 322 newtRef PkgReadNOSPart(pkg_stream_t *pkg) 323 { 324 uint32_t p_obj = PkgReadU32(pkg->part+12); 325 return PkgReadObject(pkg, p_obj&~3); 326 } 327 328 /*------------------------------------------------------------------------*/ 85 329 /** Read a part from the package file. 86 330 * … … 92 336 newtRef PkgReadPart(pkg_stream_t *pkg, int32_t index) 93 337 { 94 newtRefVar r = kNewtRefNIL; 95 // FIXME prepare pkg with offsets and pointer for reading this Part 96 // FIXME store 8/4 byte alignment flag (no so important for reading though) 97 // FIXME call PkgReadPart2 to recursively scan all Refs in the part 98 return r; 338 uint32_t flags; 339 newtRefVar frame; 340 newtRefVar ptv[] = { 341 NS_CLASS, NSSYM(PackagePart), 342 NSSYM(info), kNewtRefNIL, 343 NSSYM(flags), kNewtRefNIL, 344 NSSYM(type), kNewtRefNIL, 345 NSSYM(data), kNewtRefNIL 346 }; 347 348 pkg->part_header = pkg->part_headers + index; 349 pkg->part = pkg->data 350 + ntohl(pkg->header->directorySize) 351 + ntohl(pkg->part_header->offset); 352 flags = ntohl(pkg->part_header->flags); 353 354 frame = NewtMakeFrame2(sizeof(ptv) / (sizeof(newtRefVar) * 2), ptv); 355 356 NcSetSlot(frame, NSSYM(flags), NewtMakeInt32(flags)); 357 NcSetSlot(frame, NSSYM(type), NewtMakeBinary(kNewtRefUnbind, 358 (uint8_t*)&pkg->part_header->type, 4, true)); 359 360 switch (flags&0x03) { 361 case kNOSPart: 362 if ( PkgReadU32(pkg->part) !=0x00001041 363 || PkgReadU32(pkg->part+8)!=0x00000002) 364 { 365 # ifdef DEBUG_PKG 366 printf("*** PkgReader: PkgReadPart - unsupported NOS Part intro at %d\n", 367 pkg->part-pkg->data); 368 # endif 369 break; 370 } 371 NcSetSlot(frame, NSSYM(info), PkgReadVardataBinary(pkg, &pkg->part_header->info)); 372 NcSetSlot(frame, NSSYM(data), PkgReadNOSPart(pkg)); 373 break; 374 case kProtocolPart: 375 case kRawPart: 376 default: 377 # ifdef DEBUG_PKG 378 printf("*** PkgReader: PkgReadPart - unsupported part 0x%08x\n", flags); 379 # endif 380 break; 381 } 382 return frame; 383 } 384 385 /*------------------------------------------------------------------------*/ 386 /** Read binary data from the Variable Data area 387 * 388 * @param pkg [inout] the package 389 * @param info_ref [in] pointer to the reference 390 * 391 * @retval Binary object 392 */ 393 newtRef PkgReadVardataBinary(pkg_stream_t *pkg, pkg_info_ref_t *info_ref) 394 { 395 if (info_ref->size==0) { 396 return kNewtRefNIL; 397 } else { 398 uint8_t *src = pkg->var_len_data + ntohs(info_ref->offset); 399 int size = ntohs(info_ref->size); 400 return NewtMakeBinary(kNewtRefUnbind, src, size, true); 401 } 402 } 403 404 /*------------------------------------------------------------------------*/ 405 /** Read a UTF16 string from the Variable Data area 406 * 407 * @param pkg [inout] the package 408 * @param info_ref [in] pointer to the reference 409 * 410 * @retval String object 411 */ 412 newtRef PkgReadVardataString(pkg_stream_t *pkg, pkg_info_ref_t *info_ref) 413 { 414 if (info_ref->size==0) { 415 return kNewtRefNIL; 416 } else { 417 char *src = pkg->var_len_data + ntohs(info_ref->offset); 418 int size = ntohs(info_ref->size); 419 # ifdef HAVE_LIBICONV 420 size_t buflen; 421 char *buf = NewtIconv(pkg->from_utf16, src, size, &buflen); 422 if (buf) { 423 return NewtMakeString2(buf, buflen, false); 424 } 425 # endif /* HAVE_LIBICONV */ 426 return NewtMakeString2(src, size, false); 427 } 428 } 429 430 /*------------------------------------------------------------------------*/ 431 /** Read the package header and create a Frame object describing it. 432 * 433 * @param pkg [inout] the package 434 * 435 * @retval Frame describing the package 436 */ 437 newtRef PkgReadHeader(pkg_stream_t *pkg) 438 { 439 newtRefVar fnv[] = { 440 NS_CLASS, NSSYM(PackageHeader), 441 NSSYM(version), kNewtRefNIL, 442 NSSYM(copyright), kNewtRefNIL, 443 NSSYM(name), kNewtRefNIL, 444 NSSYM(flags), kNewtRefNIL, 445 NSSYM(parts), kNewtRefNIL 446 }; 447 newtRefVar frame = NewtMakeFrame2(sizeof(fnv) / (sizeof(newtRefVar) * 2), fnv); 448 newtRefVar parts; 449 450 NcSetSlot(frame, NSSYM(version), NSINT(pkg->verno)); 451 NcSetSlot(frame, NSSYM(copyright), PkgReadVardataString(pkg, &pkg->header->copyright)); 452 NcSetSlot(frame, NSSYM(name), PkgReadVardataString(pkg, &pkg->header->name)); 453 NcSetSlot(frame, NSSYM(flags), NewtMakeInt32(ntohl(pkg->header->flags))); 454 // all other header values can be derived form the archive itself 455 // or can be calculated at creation time 456 457 parts = NewtMakeArray(kNewtRefNIL, pkg->num_parts); 458 459 if (NewtRefIsNotNIL(parts)) 460 { 461 int32_t i, n = pkg->num_parts; 462 463 NcSetSlot(frame, NSSYM(parts), parts); 464 for (i = 0; i < n; i++) 465 { 466 NewtSetArraySlot(parts, i, PkgReadPart(pkg, i)); 467 if (pkg->lastErr != kNErrNone) break; 468 } 469 } 470 471 return frame; 99 472 } 100 473 … … 102 475 /** Read a Package and create an array of parts 103 476 * 104 * @param data [in] Package data memory 477 * @param data [in] Package data memory, can be read-only 105 478 * @param size [in] size of memory array 106 479 * … … 109 482 * @todo There is no support for relocation data yet. 110 483 */ 111 112 484 newtRef NewtReadPkg(uint8_t * data, size_t size) 113 485 { 114 486 pkg_stream_t pkg; 115 newtRef Varresult;487 newtRef result; 116 488 117 489 if (size<sizeof(pkg_header_t)) 118 return 0; // FIXME return a meaningful error490 return kNewtRefNIL; 119 491 120 492 if (!PkgIsPackage(data)) 121 return 0; // FIXME return a meaningful error493 return kNewtRefNIL; 122 494 123 495 memset(&pkg, 0, sizeof(pkg)); … … 126 498 pkg.size = size; 127 499 pkg.header = (pkg_header_t*)data; 128 129 result = NewtMakeArray(kNewtRefNIL, pkg.header->numParts+1); 130 131 if (NewtRefIsNotNIL(result)) 132 { 133 // FIXME the first slot of the array will contain information form the package 134 // FIXME header arranged in a frame 135 newtRef *slots; 136 int32_t i, n; 137 138 slots = NewtRefToSlots(result); 139 n = pkg.header->numParts; 140 141 for (i = 0; i < n; i++) 142 { 143 slots[i+1] = PkgReadPart(&pkg, i); 144 if (pkg.lastErr != kNErrNone) break; 145 } 146 } 500 pkg.num_parts = ntohl(pkg.header->numParts); 501 pkg.part_headers = (pkg_part_t*)(data + sizeof(pkg_header_t)); 502 pkg.var_len_data = data + sizeof(pkg_header_t) + pkg.num_parts*sizeof(pkg_part_t); 503 # ifdef HAVE_LIBICONV 504 { char *encoding = NewtDefaultEncoding(); 505 pkg.from_utf16 = iconv_open(encoding, "UTF-16BE"); 506 } 507 # endif /* HAVE_LIBICONV */ 508 509 result = PkgReadHeader(&pkg); 510 511 # ifdef HAVE_LIBICONV 512 iconv_close(pkg.from_utf16); 513 # endif /* HAVE_LIBICONV */ 147 514 148 515 return result; -
NEWT0/trunk/src/newt_core/incs/NewtType.h
r68 r90 104 104 105 105 106 /// Newton Package Format: Part Flags 107 enum { 108 kProtocolPart = 0, ///< part contains protocol data 109 kNOSPart = 1, ///< part contains NOS data 110 kRawPart = 2, ///< raw part data, no defined type 111 kAutoLoadFlag = 0x0010, ///< protocols will be registered automatically 112 kAutoRemoveFlag = 0x0020, ///< protocols will be unregistered automatically 113 kNotifyFlag = 0x0080, ///< notify system handler of installation 114 kAutoCopyFlag = 0x0100 ///< part must be moved into precious RAM before activation 115 }; 116 117 118 /// Newton Package Format: Object Header Flags 119 enum { 120 kObjSlotted = 0x01, ///< object is an array 121 kObjFrame = 0x02, ///< object is a frame if both flags are set 122 }; 123 124 106 125 /* 型宣言 */ 107 126 -
NEWT0/trunk/src/newt_core/incs/VC6/NewtConf.h
r87 r90 18 18 19 19 /// 名前付マジックポインタを使用 20 # define __NAMED_MAGIC_POINTER__ 120 #undef __NAMED_MAGIC_POINTER__ 21 21 22 22 /* VM */
Note: See TracChangeset
for help on using the changeset viewer.
