// HTMLAllCollections are strange objects, they support both get and call. static EncodedJSValue JSC_HOST_CALL callHTMLAllCollection(ExecState* exec) { if (exec->argumentCount() < 1) return JSValue::encode(jsUndefined()); // Do not use thisObj here. It can be the JSHTMLDocument, in the document.forms(i) case. JSHTMLAllCollection* jsCollection = jsCast<JSHTMLAllCollection*>(exec->callee()); HTMLAllCollection& collection = jsCollection->impl(); // Also, do we need the TypeError test here ? if (exec->argumentCount() == 1) { // Support for document.all(<index>) etc. String string = exec->argument(0).toString(exec)->value(exec); if (Optional<uint32_t> index = parseIndex(*string.impl())) return JSValue::encode(toJS(exec, jsCollection->globalObject(), collection.item(index.value()))); // Support for document.images('<name>') etc. return JSValue::encode(namedItems(*exec, jsCollection, Identifier::fromString(exec, string))); } // The second arg, if set, is the index of the item we want String string = exec->argument(0).toString(exec)->value(exec); if (Optional<uint32_t> index = parseIndex(*exec->argument(1).toWTFString(exec).impl())) { if (auto* item = collection.namedItemWithIndex(string, index.value())) return JSValue::encode(toJS(exec, jsCollection->globalObject(), item)); } return JSValue::encode(jsUndefined()); }
bool JSTestEventTarget::getOwnPropertySlot(JSObject* object, ExecState* state, PropertyName propertyName, PropertySlot& slot) { auto* thisObject = jsCast<JSTestEventTarget*>(object); ASSERT_GC_OBJECT_INHERITS(thisObject, info()); if (auto index = parseIndex(propertyName)) { if (index.value() < thisObject->wrapped().length()) { auto value = toJS<IDLInterface<Node>>(*state, *thisObject->globalObject(), thisObject->wrapped().item(index.value())); slot.setValue(thisObject, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly), value); return true; } return JSObject::getOwnPropertySlot(object, state, propertyName, slot); } using GetterIDLType = IDLInterface<Node>; auto getterFunctor = [] (auto& thisObject, auto propertyName) -> Optional<typename GetterIDLType::ImplementationType> { auto result = thisObject.wrapped().namedItem(propertyNameToAtomicString(propertyName)); if (!GetterIDLType::isNullValue(result)) return typename GetterIDLType::ImplementationType { GetterIDLType::extractValueFromNullable(result) }; return WTF::nullopt; }; if (auto namedProperty = accessVisibleNamedProperty<OverrideBuiltins::No>(*state, *thisObject, propertyName, getterFunctor)) { auto value = toJS<IDLInterface<Node>>(*state, *thisObject->globalObject(), WTFMove(namedProperty.value())); slot.setValue(thisObject, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly), value); return true; } return JSObject::getOwnPropertySlot(object, state, propertyName, slot); }
GetByIdStatus GetByIdStatus::computeFor(const StructureSet& set, UniquedStringImpl* uid) { // For now we only handle the super simple self access case. We could handle the // prototype case in the future. if (set.isEmpty()) return GetByIdStatus(); if (parseIndex(*uid)) return GetByIdStatus(TakesSlowPath); GetByIdStatus result; result.m_state = Simple; result.m_wasSeenInJIT = false; for (unsigned i = 0; i < set.size(); ++i) { Structure* structure = set[i]; if (structure->typeInfo().overridesGetOwnPropertySlot() && structure->typeInfo().type() != GlobalObjectType) return GetByIdStatus(TakesSlowPath); if (!structure->propertyAccessesAreCacheable()) return GetByIdStatus(TakesSlowPath); unsigned attributes; PropertyOffset offset = structure->getConcurrently(uid, attributes); if (!isValidOffset(offset)) return GetByIdStatus(TakesSlowPath); // It's probably a prototype lookup. Give up on life for now, even though we could totally be way smarter about it. if (attributes & Accessor) return GetByIdStatus(MakesCalls); // We could be smarter here, like strength-reducing this to a Call. if (!result.appendVariant(GetByIdVariant(structure, offset))) return GetByIdStatus(TakesSlowPath); } return result; }
bool LLMimeParser::parseIndex( const std::vector<U8>& buffer, LLMimeIndex& index) { LLMemoryStream mstr(&buffer[0], buffer.size()); return parseIndex(mstr, buffer.size() + 1, index); }
// ECMA 8.7.2 bool JSValue::putToPrimitive(ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) { VM& vm = exec->vm(); auto scope = DECLARE_THROW_SCOPE(vm); if (Optional<uint32_t> index = parseIndex(propertyName)) return putToPrimitiveByIndex(exec, index.value(), value, slot.isStrictMode()); // Check if there are any setters or getters in the prototype chain JSObject* obj = synthesizePrototype(exec); if (UNLIKELY(!obj)) return false; JSValue prototype; if (propertyName != exec->propertyNames().underscoreProto) { for (; !obj->structure()->hasReadOnlyOrGetterSetterPropertiesExcludingProto(); obj = asObject(prototype)) { prototype = obj->getPrototypeDirect(); if (prototype.isNull()) { if (slot.isStrictMode()) throwTypeError(exec, scope, StrictModeReadonlyPropertyWriteError); return false; } } } for (; ; obj = asObject(prototype)) { unsigned attributes; PropertyOffset offset = obj->structure()->get(vm, propertyName, attributes); if (offset != invalidOffset) { if (attributes & ReadOnly) { if (slot.isStrictMode()) throwTypeError(exec, scope, StrictModeReadonlyPropertyWriteError); return false; } JSValue gs = obj->getDirect(offset); if (gs.isGetterSetter()) return callSetter(exec, *this, gs, value, slot.isStrictMode() ? StrictMode : NotStrictMode); if (gs.isCustomGetterSetter()) return callCustomSetter(exec, gs, attributes & CustomAccessor, obj, slot.thisValue(), value); // If there's an existing property on the object or one of its // prototypes it should be replaced, so break here. break; } prototype = obj->getPrototype(vm, exec); if (vm.exception()) return false; if (prototype.isNull()) break; } if (slot.isStrictMode()) throwTypeError(exec, scope, StrictModeReadonlyPropertyWriteError); return false; }
static bool isStringOwnProperty(ExecState* exec, StringObject* object, PropertyName propertyName) { if (propertyName == exec->propertyNames().length) return true; if (Optional<uint32_t> index = parseIndex(propertyName)) { if (object->internalValue()->canGetIndex(index.value())) return true; } return false; }
bool StringObject::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName) { StringObject* thisObject = jsCast<StringObject*>(cell); if (propertyName == exec->propertyNames().length) return false; Optional<uint32_t> index = parseIndex(propertyName); if (index && thisObject->internalValue()->canGetIndex(index.value())) return false; return JSObject::deleteProperty(thisObject, exec, propertyName); }
JSValue JSHTMLAllCollection::item(ExecState& state) { VM& vm = state.vm(); auto scope = DECLARE_THROW_SCOPE(vm); if (UNLIKELY(state.argumentCount() < 1)) return throwException(&state, scope, createNotEnoughArgumentsError(&state)); String argument = state.uncheckedArgument(0).toWTFString(&state); if (Optional<uint32_t> index = parseIndex(*argument.impl())) return toJS(&state, globalObject(), wrapped().item(index.value())); return namedItems(state, this, Identifier::fromString(&state, argument)); }
struct gbIgnore* gbIgnoreNew(struct gbRelease* release) /* Load the ignore index. */ { static char *IGNORE_IDX = "etc/ignore.idx"; char ignoreIdx[PATH_LEN]; struct gbIgnore* ignore; AllocVar(ignore); safef(ignoreIdx, sizeof(ignoreIdx), "%s/%s", release->index->gbRoot, IGNORE_IDX); if (fileExists(ignoreIdx)) parseIndex(release, ignore, ignoreIdx); return ignore; }
bool KAbstractObjParserPrivate::parseFaceIndices() { // If there is no starting integer, there is no index if (!parseIndex(m_index_array[0])) { return false; } // Check for subequent indices (texture) if (checkToken(PT_SEPARATOR)) { if (!parseIndex(m_index_array[1])) { m_index_array[1] = 0; } } else { m_index_array[1] = 0; } // Check for subequent indices (normal) if (checkToken(PT_SEPARATOR)) { if (!parseIndex(m_index_array[2])) { m_index_array[2] = 0; } } else { m_index_array[2] = 0; } return true; }
bool checkIndex(PAKFile &file) { uint32 size = 0; const uint8 *data = file.getFileData("INDEX", &size); if (!data) return false; Index index = parseIndex(data, size); if (index.version != kKyraDatVersion) return false; if (index.includedGames * 2 + 8 != size) return false; return true; }
void RuntimeArray::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) { RuntimeArray* thisObject = jsCast<RuntimeArray*>(cell); if (propertyName == exec->propertyNames().length) { exec->vm().throwException(exec, createRangeError(exec, "Range error")); return; } if (Optional<uint32_t> index = parseIndex(propertyName)) { thisObject->getConcreteArray()->setValueAt(exec, index.value(), value); return; } JSObject::put(thisObject, exec, propertyName, value, slot); }
bool JSString::getStringPropertyDescriptor(ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor) { if (propertyName == exec->propertyNames().length) { descriptor.setDescriptor(jsNumber(length()), DontEnum | DontDelete | ReadOnly); return true; } std::optional<uint32_t> index = parseIndex(propertyName); if (index && index.value() < length()) { descriptor.setDescriptor(getIndex(exec, index.value()), DontDelete | ReadOnly); return true; } return false; }
bool StringObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) { VM& vm = exec->vm(); auto scope = DECLARE_THROW_SCOPE(vm); StringObject* thisObject = jsCast<StringObject*>(cell); if (UNLIKELY(isThisValueAltered(slot, thisObject))) return ordinarySetSlow(exec, thisObject, propertyName, value, slot.thisValue(), slot.isStrictMode()); if (propertyName == vm.propertyNames->length) return typeError(exec, scope, slot.isStrictMode(), ASCIILiteral(ReadonlyPropertyWriteError)); if (Optional<uint32_t> index = parseIndex(propertyName)) return putByIndex(cell, exec, index.value(), value, slot.isStrictMode()); return JSObject::put(cell, exec, propertyName, value, slot); }
bool RuntimeArray::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) { VM& vm = exec->vm(); auto scope = DECLARE_THROW_SCOPE(vm); RuntimeArray* thisObject = jsCast<RuntimeArray*>(cell); if (propertyName == exec->propertyNames().length) { throwException(exec, scope, createRangeError(exec, "Range error")); return false; } if (Optional<uint32_t> index = parseIndex(propertyName)) return thisObject->getConcreteArray()->setValueAt(exec, index.value(), value); return JSObject::put(thisObject, exec, propertyName, value, slot); }
void PropertyNameArray::add(StringImpl* identifier) { ASSERT(!identifier || (identifier == StringImpl::empty() || identifier->isAtomic() || identifier->isSymbol())); if (!ASSERT_DISABLED) { Optional<uint32_t> index = parseIndex(Identifier::fromUid(m_vm, identifier)); ASSERT_UNUSED(index, !index || index.value() >= m_previouslyEnumeratedLength); } if (m_alternateSet && m_alternateSet->contains(identifier)) return; if (!m_set->add(identifier).isNewEntry) return; addKnownUnique(identifier); }
bool RuntimeArray::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot) { RuntimeArray* thisObject = jsCast<RuntimeArray*>(object); if (propertyName == exec->propertyNames().length) { slot.setCacheableCustom(thisObject, DontDelete | ReadOnly | DontEnum, thisObject->lengthGetter); return true; } Optional<uint32_t> index = parseIndex(propertyName); if (index && index.value() < thisObject->getLength()) { slot.setValue(thisObject, DontDelete | DontEnum, thisObject->getConcreteArray()->valueAt(exec, index.value())); return true; } return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot); }
void ImageExportSerializer::parseGroup(pugi::xml_node _node, DataPtr _parent) { DataPtr data = Data::CreateInstance(); data->setType(DataTypeManager::getInstance().getType("Group")); std::string value = _node.attribute("name").value(); if (value.empty()) value = "unnamed"; data->setPropertyValue("Name", value); data->setPropertyValue("Texture", _node.attribute("texture").value()); MyGUI::IntSize size = MyGUI::IntSize::parse(_node.attribute("size").value()); data->setPropertyValue("Size", MyGUI::IntCoord(0, 0, size.width, size.height).print()); _parent->addChild(data); pugi::xpath_node_set nodes = _node.select_nodes("Index"); for (pugi::xpath_node_set::const_iterator node = nodes.begin(); node != nodes.end(); node ++) parseIndex((*node).node(), data); }
bool updateIndex(PAKFile &out, const ExtractInformation *eI) { uint32 size = 0; const uint8 *data = out.getFileData("INDEX", &size); Index index; if (data) index = parseIndex(data, size); GameDef gameDef = createGameDef(eI); if (index.version == kKyraDatVersion) { if (std::find(index.gameList.begin(), index.gameList.end(), gameDef) == index.gameList.end()) { ++index.includedGames; index.gameList.push_back(gameDef); } else { // Already included in the game list, thus we do not need any further processing here. return true; } } else { index.version = kKyraDatVersion; index.includedGames = 1; index.gameList.push_back(gameDef); } const uint32 indexBufferSize = 8 + index.includedGames * 2; uint8 *indexBuffer = new uint8[indexBufferSize]; assert(indexBuffer); uint8 *dst = indexBuffer; WRITE_BE_UINT32(dst, index.version); dst += 4; WRITE_BE_UINT32(dst, index.includedGames); dst += 4; for (Index::GameList::const_iterator i = index.gameList.begin(); i != index.gameList.end(); ++i) { WRITE_BE_UINT16(dst, *i); dst += 2; } out.removeFile("INDEX"); if (!out.addFile("INDEX", indexBuffer, indexBufferSize)) { fprintf(stderr, "ERROR: couldn't update kyra.dat INDEX\n"); delete[] indexBuffer; return false; } return true; }
// Property access sequence is: // (1) indexed properties, // (2) regular own properties, // (3) named properties (in fact, these shouldn't be on the window, should be on the NPO). bool JSDOMWindow::getOwnPropertySlot(JSObject* object, ExecState* state, PropertyName propertyName, PropertySlot& slot) { // (1) First, indexed properties. // Hand off all indexed access to getOwnPropertySlotByIndex, which supports the indexed getter. if (Optional<unsigned> index = parseIndex(propertyName)) return getOwnPropertySlotByIndex(object, state, index.value(), slot); auto* thisObject = jsCast<JSDOMWindow*>(object); auto* frame = thisObject->wrapped().frame(); // Hand off all cross-domain/frameless access to jsDOMWindowGetOwnPropertySlotRestrictedAccess. String errorMessage; if (!frame || !BindingSecurity::shouldAllowAccessToDOMWindow(*state, thisObject->wrapped(), errorMessage)) return jsDOMWindowGetOwnPropertySlotRestrictedAccess(thisObject, frame, state, propertyName, slot, errorMessage); // FIXME: this need more explanation. // (Particularly, is it correct that this exists here but not in getOwnPropertySlotByIndex?) slot.setWatchpointSet(thisObject->m_windowCloseWatchpoints); // (2) Regular own properties. PropertySlot slotCopy = slot; if (Base::getOwnPropertySlot(thisObject, state, propertyName, slot)) { // Detect when we're getting the property 'showModalDialog', this is disabled, and has its original value. bool isShowModalDialogAndShouldHide = propertyName == state->propertyNames().showModalDialog && !DOMWindow::canShowModalDialog(frame) && slot.isValue() && isHostFunction(slot.getValue(state, propertyName), jsDOMWindowInstanceFunctionShowModalDialog); // Unless we're in the showModalDialog special case, we're done. if (!isShowModalDialogAndShouldHide) return true; slot = slotCopy; } #if ENABLE(USER_MESSAGE_HANDLERS) if (propertyName == state->propertyNames().webkit && thisObject->wrapped().shouldHaveWebKitNamespaceForWorld(thisObject->world())) { slot.setCacheableCustom(thisObject, DontDelete | ReadOnly, jsDOMWindowWebKit); return true; } #endif return false; }
Face ModelLoaderOBJ::parseFace(const TOKENS &tokens) { ASSERT(isLineOfType(tokens, "f"), "Line does not contain a face"); Face result; TOKENS::const_iterator i = tokens.begin(); for (int j=0; j<3; ++j) { tuple<int, int, int> index = parseIndex(*(++i)); result.vertIndex[j] = index.get<0>(); result.coordIndex[j] = index.get<1>(); result.normalIndex[j] = index.get<2>(); ASSERT(result.vertIndex[j] >= 0, "Vertex index is negative!"); ASSERT(result.coordIndex[j] >= 0, "Tex-Coord index is negative!"); ASSERT(result.normalIndex[j] >= 0, "Normal index is negative!"); } return result; }
ALWAYS_INLINE static void JIT_OPERATION operationPutByValInternal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue) { VM* vm = &exec->vm(); NativeCallFrameTracer tracer(vm, exec); JSValue baseValue = JSValue::decode(encodedBase); JSValue property = JSValue::decode(encodedProperty); JSValue value = JSValue::decode(encodedValue); if (LIKELY(property.isUInt32())) { // Despite its name, JSValue::isUInt32 will return true only for positive boxed int32_t; all those values are valid array indices. ASSERT(isIndex(property.asUInt32())); putByVal<strict, direct>(exec, baseValue, property.asUInt32(), value); return; } if (property.isDouble()) { double propertyAsDouble = property.asDouble(); uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble); if (propertyAsDouble == propertyAsUInt32 && isIndex(propertyAsUInt32)) { putByVal<strict, direct>(exec, baseValue, propertyAsUInt32, value); return; } } // Don't put to an object if toString throws an exception. auto propertyName = property.toPropertyKey(exec); if (vm->exception()) return; PutPropertySlot slot(baseValue, strict); if (direct) { RELEASE_ASSERT(baseValue.isObject()); if (Optional<uint32_t> index = parseIndex(propertyName)) asObject(baseValue)->putDirectIndex(exec, index.value(), value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow); else asObject(baseValue)->putDirect(*vm, propertyName, value, slot); } else baseValue.put(exec, propertyName, value, slot); }
bool LLMimeParser::Impl::parseIndex( std::istream& istr, S32 limit, const std::string& separator, bool is_subpart, LLMimeIndex& index) { LLSD headers; bool parsed_something = false; if(parseHeaders(istr, limit, headers)) { parsed_something = true; LLMimeIndex mime(headers, mScanCount); index = mime; if(index.isMultipart()) { // Figure out the separator, scan past it, and recurse. std::string ct = headers[CONTENT_TYPE].asString(); std::string sep = findSeparator(ct); scanPastSeparator(istr, limit, sep); while(continueParse() && parseIndex(istr, limit, sep, true, mime)) { index.attachSubPart(mime); } } else { // Scan to the end of content. scanPastContent(istr, limit, headers, separator); if(is_subpart) { scanPastSeparator(istr, limit, separator); } } } if(mError) return false; return parsed_something; }
void ObjFile::read(std::istream& from) { std::vector<Eigen::Vector4f> points; std::vector<Eigen::Vector4f> normals; std::vector<int> indices; std::vector<int> uvIndices; std::vector<int> vnIndices; std::vector<Eigen::Vector3f> uvs; std::string curLine; while (!from.eof()) { std::getline(from, curLine); utils::trim(&curLine); if (curLine.compare(0, 2, "v ") == 0) { points.push_back(parseVertex(curLine)); } else if (curLine.compare(0, 2, "f ") == 0) { auto tuple = parseIndex(curLine); indices.insert(indices.end(), std::get<0>(tuple).begin(), std::get<0>(tuple).end()); uvIndices.insert(uvIndices.end(), std::get<1>(tuple).begin(), std::get<1>(tuple).end()); vnIndices.insert(vnIndices.end(), std::get<2>(tuple).begin(), std::get<2>(tuple).end()); } else if (curLine.compare(0, 3, "vt ") == 0) { uvs.push_back(parseUV(curLine)); } else if (curLine.compare(0, 3, "vn ") == 0) { normals.push_back(parseNormal(curLine)); } } //std::reverse(indices.begin(), indices.end()); //std::reverse(vnIndices.begin(), vnIndices.end()); //std::reverse(uvIndices.begin(), uvIndices.end()); _points = std::move(points); _indices = std::move(indices); _normals = std::move(normals); _uvIndices = std::move(uvIndices); _vnIndices = std::move(vnIndices); _uvs = std::move(uvs); }
PutByIdStatus PutByIdStatus::computeFor(JSGlobalObject* globalObject, const StructureSet& set, UniquedStringImpl* uid, bool isDirect) { if (parseIndex(*uid)) return PutByIdStatus(TakesSlowPath); if (set.isEmpty()) return PutByIdStatus(); PutByIdStatus result; result.m_state = Simple; for (unsigned i = 0; i < set.size(); ++i) { Structure* structure = set[i]; if (structure->typeInfo().overridesGetOwnPropertySlot() && structure->typeInfo().type() != GlobalObjectType) return PutByIdStatus(TakesSlowPath); if (!structure->propertyAccessesAreCacheable()) return PutByIdStatus(TakesSlowPath); unsigned attributes; PropertyOffset offset = structure->getConcurrently(uid, attributes); if (isValidOffset(offset)) { if (attributes & CustomAccessor) return PutByIdStatus(MakesCalls); if (attributes & (Accessor | ReadOnly)) return PutByIdStatus(TakesSlowPath); WatchpointSet* replaceSet = structure->propertyReplacementWatchpointSet(offset); if (!replaceSet || replaceSet->isStillValid()) { // When this executes, it'll create, and fire, this replacement watchpoint set. // That means that this has probably never executed or that something fishy is // going on. Also, we cannot create or fire the watchpoint set from the concurrent // JIT thread, so even if we wanted to do this, we'd need to have a lazy thingy. // So, better leave this alone and take slow path. return PutByIdStatus(TakesSlowPath); } PutByIdVariant variant = PutByIdVariant::replace(structure, offset, structure->inferredTypeDescriptorFor(uid)); if (!result.appendVariant(variant)) return PutByIdStatus(TakesSlowPath); continue; } // Our hypothesis is that we're doing a transition. Before we prove that this is really // true, we want to do some sanity checks. // Don't cache put transitions on dictionaries. if (structure->isDictionary()) return PutByIdStatus(TakesSlowPath); // If the structure corresponds to something that isn't an object, then give up, since // we don't want to be adding properties to strings. if (!structure->typeInfo().isObject()) return PutByIdStatus(TakesSlowPath); ObjectPropertyConditionSet conditionSet; if (!isDirect) { conditionSet = generateConditionsForPropertySetterMissConcurrently( globalObject->vm(), globalObject, structure, uid); if (!conditionSet.isValid()) return PutByIdStatus(TakesSlowPath); } // We only optimize if there is already a structure that the transition is cached to. Structure* transition = Structure::addPropertyTransitionToExistingStructureConcurrently(structure, uid, 0, offset); if (!transition) return PutByIdStatus(TakesSlowPath); ASSERT(isValidOffset(offset)); bool didAppend = result.appendVariant( PutByIdVariant::transition( structure, transition, conditionSet, offset, transition->inferredTypeDescriptorFor(uid))); if (!didAppend) return PutByIdStatus(TakesSlowPath); } return result; }
void Map::loadMap(Graphics *newGraphics, char *indexFilename) { loadGraphics(newGraphics); parseIndex(indexFilename); }
JSValue JSHTMLAllCollection::item(ExecState& state) { if (Optional<uint32_t> index = parseIndex(*state.argument(0).toString(&state)->value(&state).impl())) return toJS(&state, globalObject(), impl().item(index.value())); return namedItems(state, this, Identifier::fromString(&state, state.argument(0).toString(&state)->value(&state))); }
bool LLMimeParser::parseIndex(const U8* buffer, S32 length, LLMimeIndex& index) { LLMemoryStream mstr(buffer, length); return parseIndex(mstr, length + 1, index); }
int arread( int (*rf)( void *data, int len ), void (*process_f)(const char *fname, void *data, int len) ) { char *nametab = 0; char *arIndex = 0; char ghbuf[GHSIZE]; struct arreader a; if( GHSIZE != rf( ghbuf, GHSIZE )) { die( &a, "no hdr"); } while(1) { char fhbuf[FHSIZE]; int ret = rf( fhbuf, FHSIZE ); if( ret == 0 ) break; if( FHSIZE != ret ) { die( &a, "no fhdr"); } char r_fname[17]; strlcpy( r_fname, fhbuf, 16 ); char r_fsize[10]; strlcpy( r_fsize, fhbuf+48, 9 ); if( fhbuf[58] != 0x60u || fhbuf[59] != 0x0Au ) { //hexdump(fhbuf, FHSIZE, "", 0); printf("name '%s', size '%s' magic: %x %x\n", r_fname, r_fsize, fhbuf[58], fhbuf[59] ); die( &a, "no file magic" ); } //printf("name '%s', size '%s'\n", r_fname, r_fsize ); //printf("name '%s'\n", r_fname ); int size = (int)atol(r_fsize); pack((unsigned char *)r_fname); //printf("name '%s'\n", r_fname ); int isSlash = !strcmp( r_fname, "/" ); if(isSlash) { /* char *arIndex = calloc( size+1, 1 ); if( arIndex == 0 || size != rf( arIndex, size ) ) die( &a, "can't load /"); */ arIndex = loadall( &a, rf, size ); //printf("/=\n'%.*s'\n", size, arIndex ); parseIndex( &a, arIndex, size); } int isSlashSlash = !strcmp( r_fname, "//" ); if(isSlashSlash) { /* nametab = calloc( size+1, 1 ); if( nametab == 0 || size != rf( nametab, size ) ) die( &a, "can't load //"); */ nametab = loadall( &a, rf, size ); //printf("//=\n%.*s\n", size, nametab ); } char *fname = r_fname; if( r_fname[0] == '/' && r_fname[1] ) fname = getLongName( &a, nametab, (int) atol(r_fname+1) ); if(!isSlashSlash && !isSlash) { //rdata( rf, size, fname ); void *d = loadall( &a, rf, size ); process_f( fname, d, size ); free(d); } // align at 2 bytes if( size & 1 ) rf( fhbuf, 1 ); } if(nametab) free(nametab); if(arIndex) free(arIndex); return 0; /* die: if(nametab) free(nametab); if(arIndex) free(arIndex); return -1; */ }
void OBJFileReader::parseLine(const char*& current, const char* endOfLine) { if(matchCommand(current, "v")) positions.push_back(parseVec3(current)); else if(matchCommand(current, "vn")) normals.push_back(parseVec3(current)); else if(matchCommand(current, "vt")) texcoords.push_back(parseVec2(current)); else if(matchCommand(current, "f")) // face { int count = 0; while(!errThisLine && *current) { VertInfo nfo; nfo.pos = parseIndex(current, positions.size()); if(*current == '/') nfo.tex = parseIndex(++current, texcoords.size()); else nfo.tex = -1; if(*current == '/') nfo.norm = parseIndex(++current, normals.size()); else nfo.norm = -1; if(*current && !isspace(*current)) diagnostic(false, current, "unexpected character after vertex indices"); vertices.push_back(nfo); count++; } if(count < 3) diagnostic(false, current, "need at least 3 vertices for a face"); else if(count > 4) diagnostic(true, current, "non-tri/quad face"); FaceInfo nfo; nfo.start = vertices.size() - count; nfo.count = count; nfo.mtrl = currentMaterial; nfo.smoothing_group = currentSmoothingGroup; faces.push_back(nfo); } else if(matchCommand(current, "g")) // group { current = endOfLine; } else if(matchCommand(current, "o")) // object { current = endOfLine; } else if(matchCommand(current, "s")) // smooth shading { if(matchCommand(current, "off")) currentSmoothingGroup = -1; else currentSmoothingGroup = parseInt(current) - 1; } else if(matchCommand(current, "usemtl")) { currentMaterial = findMaterial(current); current = endOfLine; } else if(matchCommand(current, "mtllib")) { MTLFileReader mtlreader; if(!mtlreader.read((basepath + current).c_str())) diagnostic(false, current, "error reading material library"); else { materials.swap(mtlreader.materials); current = endOfLine; defaultMaterial = -1; defaultMaterial = findMaterial("default"); sVERIFY(defaultMaterial != -1); currentMaterial = defaultMaterial; } } else diagnostic(false, current, "unknown command"); }