IO_METHOD(IoFile, foreachLine) { /*doc File foreachLine(optionalLineNumber, line, message) For each line, set index to the line number of the line and line and execute aMessage. Example usage: <pre> aFile foreachLine(i, v, writeln("Line ", i, ": ", v)) aFile foreach(v, writeln("Line: ", v)) </pre> */ IoObject *result; IoSymbol *indexSlotName, *lineSlotName; IoMessage *doMessage; IoObject *newLine; int i = 0; IoState *state; IoFile_assertOpen(self, locals, m); IoMessage_foreachArgs(m, self, &indexSlotName, &lineSlotName, &doMessage); result = IONIL(self); state = IOSTATE; IoState_pushRetainPool(state); for (;;) { IoState_clearTopPool(state); newLine = IoFile_readLine(self, locals, m); if (ISNIL(newLine)) { break; } if (indexSlotName) { IoObject_setSlot_to_(locals, indexSlotName, IONUMBER(i)); } IoObject_setSlot_to_(locals, lineSlotName, newLine); result = IoMessage_locals_performOn_(doMessage, locals, locals); if (IoState_handleStatus(IOSTATE)) { break; } i ++; } IoState_popRetainPool(state); return result; }
IO_METHOD(IoNumber, repeat) { /*doc Number repeat(optionalIndex, expression) Evaluates message a number of times that corresponds to the receivers integer value. This is significantly faster than a for() or while() loop. */ IoMessage_assertArgCount_receiver_(m, 1, self); { IoState *state = IOSTATE; IoSymbol *indexSlotName; IoMessage *doMessage; double i, max = CNUMBER(self); IoObject *result = IONIL(self); if(IoMessage_argCount(m) > 1) { indexSlotName = IoMessage_name(IoMessage_rawArgAt_(m, 0)); doMessage = IoMessage_rawArgAt_(m, 1); } else { indexSlotName = 0; doMessage = IoMessage_rawArgAt_(m, 0); } IoState_pushRetainPool(state); for (i = 0; i < max; i ++) { /* if (result != locals && result != self) { IoState_immediatelyFreeIfUnreferenced_(state, result); } */ IoState_clearTopPool(state); if (indexSlotName) { IoObject_setSlot_to_(locals, indexSlotName, IONUMBER(i)); } result = IoMessage_locals_performOn_(doMessage, locals, locals); if (IoState_handleStatus(IOSTATE)) { break; } } IoState_popRetainPoolExceptFor_(IOSTATE, result); return result; } }
IO_METHOD(IoFile, foreach) { /*doc File foreach(optionalIndex, value, message) For each byte, set index to the index of the byte and value to the number containing the byte value and execute aMessage. Example usage: <p> <pre> aFile foreach(i, v, writeln("byte at ", i, " is ", v)) aFile foreach(v, writeln("byte ", v)) </pre> */ IoObject *result; IoSymbol *indexSlotName, *characterSlotName; IoMessage *doMessage; int i = 0; IoFile_assertOpen(self, locals, m); result = IONIL(self); IoMessage_foreachArgs(m, self, &indexSlotName, &characterSlotName, &doMessage); for (;;) { int c = getc(DATA(self)->stream); if (c == EOF) { break; } if (indexSlotName) { IoObject_setSlot_to_(locals, indexSlotName, IONUMBER(i)); } IoObject_setSlot_to_(locals, characterSlotName, IONUMBER(c)); result = IoMessage_locals_performOn_(doMessage, locals, locals); if (IoState_handleStatus(IOSTATE)) { break; } i ++; } return result; }