IoObject *IoFont_drawString(IoFont *self, IoObject *locals, IoMessage *m) { /*doc Font drawString(aString, optionalStartIndex, optionalEndIndex) Draws aString using the optional start and end indexes, if supplied. Returns self. <p> Note; Fonts are drawn as RGBA pixel maps. These blending options are recommended: <pre> glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) </pre> */ IoSymbol *textString = IoMessage_locals_seqArgAt_(m, locals, 0); int startIndex = 0; int endIndex; if (IoMessage_argCount(m) > 1) { startIndex = IoNumber_asInt(IoMessage_locals_numberArgAt_(m, locals, 1)); if (startIndex > (int)IoSeq_rawSize(textString)) startIndex = (int)IoSeq_rawSize(textString); } if (IoMessage_argCount(m) > 2) { endIndex = IoNumber_asInt(IoMessage_locals_numberArgAt_(m, locals, 2)); } else { endIndex = IoSeq_rawSize(textString); } GLFont_drawString(DATA(self)->font, CSTRING(textString) , startIndex, endIndex); IoFont_checkError(self, locals, m); return self; }
IoObject *IoFont_lengthOfString(IoFont *self, IoObject *locals, IoMessage *m) { /*doc Font widthOfString(aString) Returns a Number with the width that aString would render to with the receiver's current settings. */ IoSymbol *text = IoMessage_locals_seqArgAt_(m, locals, 0); int startIndex = 0; int max = IoSeq_rawSize(text); int endIndex = max; if (IoMessage_argCount(m) == 2) { startIndex = IoNumber_asInt(IoMessage_locals_numberArgAt_(m, locals, 1)); if (startIndex > max) startIndex = max; } if (IoMessage_argCount(m) > 2) { endIndex = IoNumber_asInt(IoMessage_locals_numberArgAt_(m, locals, 2)); if (startIndex > max) endIndex = max; } return IONUMBER( GLFont_lengthOfString( DATA(self)->font, CSTRING(text), startIndex, endIndex) ); }
IoObject *IoCurses_setScrollingRegion(IoCurses *self, IoObject *locals, IoMessage *m) { /*doc Curses setScrollingRegion(top, bottom) Sets the scrolling region; top and bottom are the line numbers of the top and button margin. Returns self. */ int top = IoNumber_asInt(IoMessage_locals_numberArgAt_(m, locals, 0)); int bot = IoNumber_asInt(IoMessage_locals_numberArgAt_(m, locals, 1)); if(setscrreg(top, bot) == ERR) { IoCurses_showError(self, m, "Curses.scroll", "Failed to set the scrolling region."); } return self; }
int Levels_levelForOp(Levels *self, char *messageName, IoSymbol *messageSymbol, IoMessage *msg) { IoObject *value = IoMap_rawAt(self->operatorTable, messageSymbol); if (!value) { return -1; } if (ISNUMBER(value)) { int precedence = IoNumber_asInt((IoNumber*)value); if (precedence < 0 || precedence >= IO_OP_MAX_LEVEL) { IoState_error_(IoObject_state(msg), msg, "compile error: Precedence for operators must be between 0 and %d. Precedence was %d.", IO_OP_MAX_LEVEL - 1, precedence); } return precedence; } else { IoState_error_(IoObject_state(msg), msg, "compile error: Value for '%s' in Message OperatorTable operators is not a number. Values in the OperatorTable operators are numbers which indicate the precedence of the operator.", messageName); return -1; // The C compiler does not know that IoState_error_() will never return. } }
IO_METHOD(IoSeq, asBinaryNumber) { /*doc Sequence asBinaryNumber Returns a Number containing the first 8 bytes of the receiver without casting them to a double. Endian is same as machine. */ IoNumber *byteCount = IoMessage_locals_valueArgAt_(m, locals, 0); size_t max = UArray_size(DATA(self)); int bc = sizeof(double); double d = 0; if (!ISNIL(byteCount)) { bc = IoNumber_asInt(byteCount); } if (max < bc) { IoState_error_(IOSTATE, m, "requested first %i bytes, but Sequence only contians %i bytes", bc, max); } memcpy(&d, UArray_bytes(DATA(self)), bc); return IONUMBER(d); }
intptr_t bouncer(IoBlock *self, intptr_t ret, intptr_t a, intptr_t b, intptr_t c, intptr_t d, intptr_t e) { IoObject *lobby = IoState_lobby(IOSTATE); IoNumber *n; static IoMessage *m = NULL; List *argNames = ((IoBlockData*)IoObject_dataPointer(self))->argNames; if (m == NULL) m = IoMessage_new(IOSTATE); if (0 < argNames->size) IoMessage_setCachedArg_toInt_(m, 0, (int)a); if (1 < argNames->size) IoMessage_setCachedArg_toInt_(m, 1, (int)b); if (2 < argNames->size) IoMessage_setCachedArg_toInt_(m, 2, (int)c); if (3 < argNames->size) IoMessage_setCachedArg_toInt_(m, 3, (int)d); if (4 < argNames->size) IoMessage_setCachedArg_toInt_(m, 4, (int)e); n = IoBlock_activate(self, lobby, lobby, m, lobby); if (ISNUMBER(n)) { return (intptr_t)IoNumber_asInt(n); } return 0; }
IoObject *IoCurses_move(IoCurses *self, IoObject *locals, IoMessage *m) { /*doc Curses move(x, y) Moves the cursor to column y and row x on the terminal. (0, 0) is at the top-left of the terminal. Returns self. */ int x = IoNumber_asInt(IoMessage_locals_numberArgAt_(m, locals, 0)); int y = IoNumber_asInt(IoMessage_locals_numberArgAt_(m, locals, 1)); if (move(y, x) == ERR) { IoCurses_showError(self, m, "Curses.move", "Failed to move cursor."); } return self; }
IoObject *IoFont_lengthOfCharacter(IoFont *self, IoObject *locals, IoMessage *m) { /*doc Font widthOfCharacter(aNumber) Returns the width of the character specified by aNumber in the receiver's font. */ unsigned char c = IoNumber_asInt(IoMessage_locals_numberArgAt_(m, locals, 0)); return IONUMBER( GLFont_lengthOfCharacter_( DATA(self)->font, c) ); }
IoObject *IoFont_stringIndexAtWidth(IoFont *self, IoObject *locals, IoMessage *m) { /*doc Font stringIndexAtWidth(aString, startIndex, width) Returns the max index of the character in String (starting at startIndex) that fits within width. */ IoSymbol *text = IoMessage_locals_seqArgAt_(m, locals, 0); int startIndex; int width; //IOASSERT(IoMessage_argCount(m) == 2, "requires 3 arguments"); startIndex = IoNumber_asInt(IoMessage_locals_numberArgAt_(m, locals, 1)); if (startIndex > (int)IoSeq_rawSize(text)) startIndex = (int)IoSeq_rawSize(text); width = IoNumber_asInt(IoMessage_locals_numberArgAt_(m, locals, 2)); return IONUMBER(GLFont_stringIndexAtWidth(DATA(self)->font, CSTRING(text), startIndex, width)); }
IO_METHOD(IoMessage, argAt) { /*doc Message argAt(indexNumber) Returns Message object for the specified argument or Nil if none exists. */ int index = IoNumber_asInt(IoMessage_locals_numberArgAt_(m , locals, 0)); IoObject *v = List_at_(DATA(self)->args, index); return v ? v : IONIL(self); }
IoObject* IoMySQL_connect(IoObject* self, IoObject* locals, IoMessage* m) { IoObject *host = NULL, *user = NULL, *password = NULL, *database = NULL, *port = NULL, *socket = NULL, *ssl = NULL; /*doc MySQL connect(host, user, password, database, port, unixSocket, useSSL) Connect to a MySQL database. */ switch(IoMessage_argCount(m)) { case 7: ssl = IoMessage_locals_quickValueArgAt_(m, locals, 6); case 6: socket = IoMessage_locals_quickValueArgAt_(m, locals, 5); case 5: port = IoMessage_locals_quickValueArgAt_(m, locals, 4); case 4: database = IoMessage_locals_quickValueArgAt_(m, locals, 3); case 3: password = IoMessage_locals_quickValueArgAt_(m, locals, 2); case 2: user = IoMessage_locals_quickValueArgAt_(m, locals, 1); case 1: host = IoMessage_locals_quickValueArgAt_(m, locals, 0); } if(DATA(self)->connected) { mysql_close(&DATA(self)->connection); DATA(self)->connected = 0; } if(mysql_real_connect( &DATA(self)->connection, host && ISSEQ(host) ? IoSeq_asCString(host) : NULL, user && ISSEQ(user) ? IoSeq_asCString(user) : NULL, password && ISSEQ(password) ? IoSeq_asCString(password) : NULL, database && ISSEQ(database) ? IoSeq_asCString(database) : NULL, port && ISNUMBER(port) ? (unsigned) IoNumber_asInt(port) : 0, socket && ISSEQ(socket) ? IoSeq_asCString(socket) : NULL, ssl && ISFALSE(ssl) ? 0 : CLIENT_SSL )) { DATA(self)->connected = 1; IoObject_setSlot_to_(self, IOSYMBOL("host"), host ? host : IONIL(self)); IoObject_setSlot_to_(self, IOSYMBOL("user"), user ? user : IONIL(self)); IoObject_setSlot_to_(self, IOSYMBOL("password"), password ? password : IONIL(self)); IoObject_setSlot_to_(self, IOSYMBOL("database"), database ? database : IONIL(self)); IoObject_setSlot_to_(self, IOSYMBOL("port"), port ? port : IONIL(self)); IoObject_setSlot_to_(self, IOSYMBOL("socket"), socket ? socket : IONIL(self)); IoObject_setSlot_to_(self, IOSYMBOL("usingSSL"), ssl ? IOBOOL(self, ISTRUE(ssl)) : IOFALSE(self)); } else IoState_error_(IOSTATE, m, "connection error(%d): %s", mysql_errno(&DATA(self)->connection), mysql_error(&DATA(self)->connection)); return self; }
IoObject *IoCurses_nodelay(IoCurses *self, IoObject *locals, IoMessage *m) { /*doc Curses nodelay(aBoolean) Enables or disables block during read. If aNumber is zero, nodelay is set to be false, otherwise it is set to be true. */ int b = IoNumber_asInt(IoMessage_locals_numberArgAt_(m, locals, 0)); nodelay(stdscr, b); return self; }
intptr_t marshal(IoDynLib *self, IoObject *arg) { intptr_t n = 0; if (ISNUMBER(arg)) { n = IoNumber_asInt(arg); } else if (ISSYMBOL(arg)) { n = (intptr_t)CSTRING(arg); } else if (ISLIST(arg)) { int i; intptr_t *l = io_calloc(1, IoList_rawSize(arg) * sizeof(intptr_t)); for (i = 0; i < IoList_rawSize(arg); i ++) l[i] = marshal(self, List_rawAt_(IoList_rawList(arg), i)); n = (intptr_t)l; } else if (ISBUFFER(arg)) { n = (intptr_t)IoSeq_rawBytes(arg); } else if (ISBLOCK(arg)) { unsigned char *blk = io_calloc(1, 20), *p = blk; // FIXME: need trampoline code for other architectures *p++ = 0x68; *((intptr_t *)p) = (intptr_t)arg; p += sizeof(intptr_t); *p++ = 0xb8; *((intptr_t *)p) = (intptr_t)bouncer; p += sizeof(intptr_t); *p++ = 0xff; *p++ = 0xd0; *p++ = 0x83; *p++ = 0xc4; *p++ = 0x04; *p++ = 0xc3; n = (intptr_t)blk; } else { n = (intptr_t)arg; //IONIL(self); } return n; }
IoValue *IoSocket_asyncReadLine(IoSocket *self, IoValue *locals, IoMessage *m) { if(self->activeReadLine) { delete self->activeReadLine; } IoNumber *size = (IoNumber*)IoMessage_locals_numberArgAt_(m, locals, 0); int trueSize = IoNumber_asInt(size); char* buffer = (char*)malloc(trueSize + 1); memset(buffer, 0, trueSize + 1); self->activeReadLine = CReadLineSocket::NewL(self->socket, self, buffer, trueSize); self->activeReadLine->StartReadLineL(); return (IoValue*)self; }
IoValue *IoSocket_read(IoSocket *self, IoValue *locals, IoMessage *m) { IoNumber *size = (IoNumber*)IoMessage_locals_numberArgAt_(m, locals, 0); IoState* state = (IoState*)self->tag->state; int trueSize = IoNumber_asInt(size); char* buffer = (char*)malloc(trueSize + 1); memset(buffer, 0, trueSize + 1); TInt status = self->socket->ReadOneOrMore(buffer, trueSize); if(status != 0) { IoState_error_description_(state, "IoSocket.read", "RSocket.Read: '%d'\n", status); } IoValue* result = (IoValue*)USTRING(buffer); free(buffer); return result; }
IoObject *IoCurses_scroll(IoCurses *self, IoObject *locals, IoMessage *m) { /*doc Curses scroll(num) Scrolls up num lines. num is optional and defaults to 1. Returns self. */ int num = 1; if (IoMessage_argCount(m) > 0) { num = IoNumber_asInt(IoMessage_locals_numberArgAt_(m, locals, 0)); } if (scrl(num) == ERR) { IoCurses_showError(self, m, "Curses.scroll", "Failed to scroll screen."); } return self; }
IoObject *IoCurses_input(IoCurses *self, IoObject *locals, IoMessage *m) { /*doc Curses input(n) Returns user input up to a return, or a maximun of n characters. */ int length = 1; char string[length+1]; if (IoMessage_argCount(m) > 0) { length = IoNumber_asInt(IoMessage_locals_numberArgAt_(m, locals, 0)); } if (innstr(string, length) == ERR) { return IONIL(self); } return IoState_symbolWithCString_(IOSTATE, string); }
IoObject *IoCurses_get(IoCurses *self, IoObject *locals, IoMessage *m) { /*doc Curses get(n) Returns n characters from the terminal. n is optional and defaults to 1. */ int inputCharacterLimit = IO_CURSES_INPUT_BUFFER_LENGTH; char string[inputCharacterLimit]; if (IoMessage_argCount(m) > 0) { IoNumber *number = IoMessage_locals_numberArgAt_(m, locals, 0); inputCharacterLimit = IoNumber_asInt(number); } if (getnstr(string, inputCharacterLimit) == ERR) { return IONIL(self); } return IoState_symbolWithCString_(IOSTATE, string); }
IoObject *IoCurses_delete(IoCurses *self, IoObject *locals, IoMessage *m) { /*doc Curses delete(n) Deletes n characters at the current position. Text to the right is shifted left. n is optional and defaults to 1. Returns self. */ int n = 1; if (IoMessage_argCount(m) > 0) { n = IoNumber_asInt(IoMessage_locals_numberArgAt_(m, locals, 0)); } for (n = n; n > 0; n--) { if (delch() == ERR) { IoCurses_showError(self, m, "Curses.delete", "Failed to delete string."); } } return self; }
IoValue *IoSocket_readLine(IoSocket *self, IoValue *locals, IoMessage *m) { IoNumber *size = (IoNumber*)IoMessage_locals_numberArgAt_(m, locals, 0); IoState* state = (IoState*)self->tag->state; if(self->activeReadLine) { delete self->activeReadLine; self->activeReadLine = 0; } int trueSize = IoNumber_asInt(size); char* buffer = (char*)malloc(trueSize + 1); memset(buffer, 0, trueSize + 1); self->activeReadLine = CReadLineSocket::NewL(self->socket, self, buffer, trueSize); self->activeReadLine->StartReadLineL(); while(!self->lineRead) { IoState_yield(state); } IoValue* value = (IoValue*)USTRING(self->lineRead); free(self->lineRead); self->lineRead = 0; return (IoValue*)value; }
IoObject *IoRegexMatches_setEndPosition(IoRegexMatches *self, IoObject *locals, IoMessage *m) { /*doc RegexMatches setEndPosition(anIndex) Sets the index in the string where the receiver should stop searching. It will be as if the string ends at that index. If <em>index</em> is nil, the end position will be set to the end of string. Returns self. <pre> Io> "funkadelic" matchesOfRegex("\\w+") setEndPosition(4) next string ==> funk Io> "funkadelic" matchesOfRegex("\\w+") setEndPosition(nil) next string ==> funkadelic </pre> */ IoObject *arg = IoMessage_locals_valueArgAt_(m, locals, 0); int stringLength = IoSeq_rawSize(DATA(self)->string); int endPos = stringLength; if (ISNIL(arg)) { DATA(self)->endPosition = endPos; return self; } if (!ISNUMBER(arg)) IoState_error_(IOSTATE, m, "The argument to setEndPosition must be either a Number or nil"); endPos = IoNumber_asInt(arg); if (endPos < 0) endPos = 0; else if (endPos > stringLength) endPos = stringLength; DATA(self)->endPosition = endPos; return self; }
IoValue *IoSocket_port_(IoSocket *self, IoValue *locals, IoMessage *m) { IoNumber *port = (IoNumber*)IoMessage_locals_numberArgAt_(m, locals, 0); self->port = IoNumber_asInt(port); return (IoValue *)self; }
int IoMessage_locals_intArgAt_(IoMessage *self, IoObject *locals, int n) { return IoNumber_asInt(IoMessage_locals_numberArgAt_(self, locals, n)); }
IoValue *IoSocket_isConnected_(IoSocket *self, IoValue *locals, IoMessage *m) { IoNumber *isConnected = (IoNumber*)IoMessage_locals_numberArgAt_(m, locals, 0); self->isConnected = IoNumber_asInt(isConnected); return (IoValue *)self; }