fixed a compiler bug in compile_expression_primary. before the fix, the compiler could treat an undotted identifier as dotted.

changed a few primitive function names in sck.c
wrote some methods for ByteStream
This commit is contained in:
hyunghwan.chung 2018-06-16 16:45:17 +00:00
parent 69bdd55579
commit ca9cc763d9
5 changed files with 145 additions and 53 deletions

View File

@ -128,9 +128,9 @@ class HttpSocket(SyncSocket)
'IM RUNNING SERVICE...............' dump. 'IM RUNNING SERVICE...............' dump.
(* (*
self readBytes: buf. self readBytesInto: buf.
buf dump. buf dump.
self readBytes: buf. self readBytesInto: buf.
buf dump. buf dump.
*) *)
@ -317,7 +317,7 @@ class MyObject(Object)
| nbytes | | nbytes |
while (true) while (true)
{ {
nbytes := csck readBytes: buf. nbytes := csck readBytesInto: buf.
if (nbytes <= 0) if (nbytes <= 0)
{ {
if (nbytes == 0) { csck close }. if (nbytes == 0) { csck close }.
@ -326,11 +326,11 @@ class MyObject(Object)
}. }.
buf dump. buf dump.
csck writeBytes: buf offset: 0 length: nbytes. csck writeBytesFrom: buf offset: 0 length: nbytes.
}. }.
]. ].
clisck onEvent: #data_out do: [ :csck | clisck onEvent: #data_out do: [ :csck |
##csck writeBytes: #[ $a, $b, C'\n' ]. ##csck writeBytesFrom: #[ $a, $b, C'\n' ].
]. ].
clisck onEvent: #closed do: [ :csck | clisck onEvent: #closed do: [ :csck |
'Socket CLOSED....' dump. 'Socket CLOSED....' dump.
@ -353,8 +353,8 @@ class MyObject(Object)
s onEvent: #connected do: [ :sck :state | s onEvent: #connected do: [ :sck :state |
if (state) if (state)
{ {
s writeBytes: #[ $a, $b, $c ]. s writeBytesFrom: #[ $a, $b, $c ].
s writeBytes: #[ $d, $e, $f ]. s writeBytesFrom: #[ $d, $e, $f ].
} }
else else
{ {
@ -366,7 +366,7 @@ class MyObject(Object)
| nbytes | | nbytes |
while (true) while (true)
{ {
nbytes := sck readBytes: buf. nbytes := sck readBytesInto: buf.
if (nbytes <= 0) if (nbytes <= 0)
{ {
if (nbytes == 0) { sck close }. if (nbytes == 0) { sck close }.
@ -377,7 +377,7 @@ class MyObject(Object)
}. }.
]. ].
s onEvent: #data_out do: [ :sck | s onEvent: #data_out do: [ :sck |
if (count < 10) { sck writeBytes: #[ $a, $b, C'\n' ]. count := count + 1. }. if (count < 10) { sck writeBytesFrom: #[ $a, $b, C'\n' ]. count := count + 1. }.
]. ].
s connect: (SocketAddress fromString: '127.0.0.1:9999'). s connect: (SocketAddress fromString: '127.0.0.1:9999').

View File

@ -243,18 +243,18 @@ class Socket(Object) from 'sck'
method(#primitive) _connect: addr. method(#primitive) _connect: addr.
method(#primitive) _socketError. method(#primitive) _socketError.
method(#primitive) _readBytes: bytes. method(#primitive) _readBytesInto: bytes.
method(#primitive) _readBytes: bytes offset: offset length: length. method(#primitive) _readBytesInto: bytes offset: offset length: length.
method(#primitive) _writeBytes: bytes. method(#primitive) _writeBytesFrom: bytes.
method(#primitive) _writeBytes: bytes offset: offset length: length. method(#primitive) _writeBytesFrom: bytes offset: offset length: length.
method(#class) new { self messageProhibited: #new } method(#class) new { self messageProhibited: #new }
method(#class) new: size { self messageProhibited: #new: } method(#class) new: size { self messageProhibited: #new: }
method(#class) __with: handle method(#class) __with_handle: handle
{ {
###self addToBeFinalized. ###self addToBeFinalized.
^(self basicNew initialize) __open(handle) ^(super new) __open(handle)
} }
method(#class) family: family type: type method(#class) family: family type: type
@ -263,7 +263,7 @@ class Socket(Object) from 'sck'
## new is prohibited. so use _basicNew with initialize. ## new is prohibited. so use _basicNew with initialize.
##^(self new) open(family, type, 0) ##^(self new) open(family, type, 0)
^(self basicNew initialize) open(family, type, 0) ^(super new) open(family, type, 0)
} }
method close method close
@ -305,10 +305,11 @@ class SyncSocket(Socket)
method(#class) new { self messageProhibited: #new } method(#class) new { self messageProhibited: #new }
method(#class) new: size { self messageProhibited: #new: } method(#class) new: size { self messageProhibited: #new: }
method(#class) __with: handle (*
method(#class) __with_handle: handle
{ {
###self addToBeFinalized. ###self addToBeFinalized.
^(self basicNew initialize) __open(handle) ^(super new) __open(handle)
} }
method(#class) family: family type: type method(#class) family: family type: type
@ -317,8 +318,9 @@ class SyncSocket(Socket)
## new is prohibited. so use _basicNew with initialize. ## new is prohibited. so use _basicNew with initialize.
##^(self new) open(family, type, 0) ##^(self new) open(family, type, 0)
^(self basicNew initialize) open(family, type, 0) ^(super new) open(family, type, 0)
} }
*)
method initialize method initialize
{ {
@ -386,45 +388,45 @@ class SyncSocket(Socket)
}. }.
} }
method readBytes: bytes method readBytesInto: bytes
{ {
| n | | n |
while (true) while (true)
{ {
n := super _readBytes: bytes. n := super _readBytesInto: bytes.
if (n >= 0) { ^n }. if (n >= 0) { ^n }.
self __wait_for_input. self __wait_for_input.
} }
} }
method readBytes: bytes offset: offset length: length method readBytesInto: bytes offset: offset length: length
{ {
| n | | n |
while (true) while (true)
{ {
n := super _readBytes: bytes offset: offset length: length. n := super _readBytesInto: bytes offset: offset length: length.
if (n >= 0) { ^n }. if (n >= 0) { ^n }.
self __wait_for_input. self __wait_for_input.
} }
} }
method writeBytes: bytes method writeBytesFrom: bytes
{ {
| n | | n |
while (true) while (true)
{ {
n := super _writeBytes: bytes. n := super _writeBytesFrom: bytes.
if (n >= 0) { ^n }. if (n >= 0) { ^n }.
self __wait_for_output. self __wait_for_output.
} }
} }
method writeBytes: bytes offset: offset length: length method writeBytesFrom: bytes offset: offset length: length
{ {
| n | | n |
while (true) while (true)
{ {
n := super _writeBytes: bytes offset: offset length: length. n := super _writeBytesFrom: bytes offset: offset length: length.
if (n >= 0) { ^n }. if (n >= 0) { ^n }.
self __wait_for_output. self __wait_for_output.
} }
@ -467,7 +469,7 @@ class AsyncSocket(Socket)
while (rem > 0) while (rem > 0)
{ {
nbytes := self _writeBytes: self.pending_bytes offset: pos length: rem. nbytes := self _writeBytesFrom: self.pending_bytes offset: pos length: rem.
if (nbytes <= -1) { break }. if (nbytes <= -1) { break }.
pos := pos + nbytes. pos := pos + nbytes.
rem := rem - nbytes. rem := rem - nbytes.
@ -529,17 +531,17 @@ class AsyncSocket(Socket)
thisProcess addAsyncSemaphore: self.outdonesem. thisProcess addAsyncSemaphore: self.outdonesem.
} }
method readBytes: bytes method readBytesInto: bytes
{ {
^super _readBytes: bytes. ^super _readBytesInto: bytes.
} }
method readBytes: bytes offset: offset length: length method readBytesInto: bytes offset: offset length: length
{ {
^super _readBytes: bytes offset: offset length: length. ^super _readBytesInto: bytes offset: offset length: length.
} }
method writeBytes: bytes offset: offset length: length method writeBytesFrom: bytes offset: offset length: length
{ {
| n pos rem | | n pos rem |
@ -557,7 +559,7 @@ class AsyncSocket(Socket)
while (rem > 0) while (rem > 0)
{ {
n := self _writeBytes: bytes offset: pos length: rem. n := self _writeBytesFrom: bytes offset: pos length: rem.
if (n <= -1) { break }. if (n <= -1) { break }.
rem := rem - n. rem := rem - n.
pos := pos + n. pos := pos + n.
@ -577,9 +579,9 @@ class AsyncSocket(Socket)
self.outreadysem signalOnOutput: self.handle. self.outreadysem signalOnOutput: self.handle.
} }
method writeBytes: bytes method writeBytesFrom: bytes
{ {
^self writeBytes: bytes offset: 0 length: (bytes size) ^self writeBytesFrom: bytes offset: 0 length: (bytes size)
} }
##method onSocketClosed ##method onSocketClosed
@ -674,7 +676,7 @@ class AsyncServerSocket(AsyncSocket)
##if (fd >= 0) ##if (fd >= 0)
if (fd notNil) if (fd notNil)
{ {
clisck := (self acceptedSocketClass) __with: fd. clisck := (self acceptedSocketClass) __with_handle: fd.
clisck beWatched. clisck beWatched.
self onSocketAccepted: clisck from: cliaddr. self onSocketAccepted: clisck from: cliaddr.
}. }.
@ -743,7 +745,7 @@ class ListenerSocket(Socket)
##if (fd >= 0) ##if (fd >= 0)
if (fd notNil) if (fd notNil)
{ {
clisck := (self acceptedSocketClass) __with: fd. clisck := (self acceptedSocketClass) __with_handle: fd.
sg addSemaphore: self.inreadysem. sg addSemaphore: self.inreadysem.
self.inreadysem signalOnInput: self.handle. self.inreadysem signalOnInput: self.handle.

View File

@ -129,8 +129,8 @@ class ExternalStream(ReadWriteStream)
## mimic java's interface... ## mimic java's interface...
interface ByteStreamable interface ByteStreamable
{ {
readBytes: readBytesInto:
writeBytes: writeBytesFrom:
} }
*) *)
@ -173,7 +173,7 @@ difficulty: how to ensure that the class implements the defined interface?
Let me think about it.. Let me think about it..
*) *)
class ByteStream(Object) ### [ByteStreamable, ByteXXX] class ByteStreamAdapter(Object) ### [ByteStreamable, ByteXXX]
{ {
var bsobj. var bsobj.
var inbuf. var inbuf.
@ -181,6 +181,10 @@ class ByteStream(Object) ### [ByteStreamable, ByteXXX]
var inlen. var inlen.
var indown. var indown.
var outbuf.
var outlen.
var outdown.
method(#class) new method(#class) new
{ {
self messageProhibited: #new. self messageProhibited: #new.
@ -195,10 +199,15 @@ class ByteStream(Object) ### [ByteStreamable, ByteXXX]
{ {
super initialize. super initialize.
self.bsobj := nil. self.bsobj := nil.
self.inbuf := ByteArray new: 1024. self.inbuf := ByteArray new: 1024.
self.inpos := 0. self.inpos := 0.
self.inlen := 0. self.inlen := 0.
self.indown := false. self.indown := false.
self.outbuf := ByteArray new: 1024.
self.outlen := 0.
self.outdown := false.
} }
method(#class) on: bsobj method(#class) on: bsobj
@ -214,7 +223,7 @@ class ByteStream(Object) ### [ByteStreamable, ByteXXX]
method __fill_inbuf method __fill_inbuf
{ {
| v | | v |
v := self.bsobj readBytes: self.inbuf. v := self.bsobj readBytesInto: self.inbuf.
## if the streamable object is not blocking, it may return an ## if the streamable object is not blocking, it may return an
## error object when data is not ready. ## error object when data is not ready.
if (v isError) { ^v }. if (v isError) { ^v }.
@ -238,7 +247,7 @@ class ByteStream(Object) ### [ByteStreamable, ByteXXX]
if (self.inpos >= self.inlen) if (self.inpos >= self.inlen)
{ {
v := self __fill_inbuf. v := self __fill_inbuf.
if (v isError) { ^v }. if (v isError) { ^v }. ## TODO: change error handling
if (v <= 0) { ^nil }. if (v <= 0) { ^nil }.
####if (self.inpos >= self.inlen) { ^nil }. ####if (self.inpos >= self.inlen) { ^nil }.
}. }.
@ -251,7 +260,7 @@ class ByteStream(Object) ### [ByteStreamable, ByteXXX]
method next: count into: byte_array startingAt: pos method next: count into: byte_array startingAt: pos
{ {
## return the count bytes ## return the count bytes
| taken avail needed v | | taken avail needed v incapa |
if (self.indown) { ^0 }. if (self.indown) { ^0 }.
@ -260,19 +269,33 @@ class ByteStream(Object) ### [ByteStreamable, ByteXXX]
## if the parameters cannot meet this assumption, you will get ## if the parameters cannot meet this assumption, you will get
## into various system exceptions. ## into various system exceptions.
needed := count. needed := count.
incapa := self.inbuf size.
while (needed > 0) while (needed > 0)
{ {
avail := self.inlen - self.inpos. avail := self.inlen - self.inpos.
if (avail <= 0) if (avail <= 0)
{ {
v := self __fill_inbuf. if (needed >= incapa)
if (v isError or v <= 0) { break }. ## <<< TODO: change the error handling {
## don't rely on the internal buffer if the number of bytes
## needed are equal to or greater than the capacity of the
## buffer.
v := self.bsobj readBytesInto: byte_array offset: pos length: needed.
if (v isError or v <= 0) { break }. ## <<< TODO: change the error handling
pos := pos + v.
needed := needed - v.
continue.
}
else
{
v := self __fill_inbuf.
if (v isError or v <= 0) { break }. ## <<< TODO: change the error handling
}.
}. }.
taken := if (avail <= needed) { avail } else { needed }. taken := if (avail <= needed) { avail } else { needed }.
byte_array replaceFrom: pos count: taken with: self.inbuf startingAt: self.inpos. byte_array replaceFrom: pos count: taken with: self.inbuf startingAt: self.inpos.
self.inpos := self.inpos + taken. self.inpos := self.inpos + taken.
pos := pos + taken. pos := pos + taken.
needed := needed - taken. needed := needed - taken.
@ -281,5 +304,72 @@ class ByteStream(Object) ### [ByteStreamable, ByteXXX]
^count - needed. ^count - needed.
} }
method nextPut: count from: byte_array startingAt: pos
{
| consumed free rem outcapa |
if (self.outdown) { ^0 }.
rem := count.
outcapa := self.outbuf size.
while (rem > 0)
{
free := outcapa - self.outlen.
if (free <= 0)
{
self flush. ## TODO: error handling...
}.
if (self.outlen <= 0 and rem >= outcapa)
{
consumed := self.bsobj writeBytesFrom: byte_array offset: pos length: rem.
if (consumed <= 0) { break }. ## TODO: error handling. also handle exceptions
}
else
{
consumed := if (free <= rem) { free } else { rem }.
self.outbuf replaceFrom: self.outlen count: consumed with: byte_array startingAt: pos.
self.outlen := self.outlen + consumed.
}.
pos := pos + consumed.
rem := rem - consumed.
}.
^count - rem.
}
method flush
{
| v pos |
pos := 0.
while (pos < self.outlen)
{
v := self.bsobj writeBytesFrom: self.outbuf offset: pos length: (self.outlen - pos).
if (v <= 0) { break }. ## TODO: error handling. also handle exceptions
pos := pos + v.
}.
self.outlen := 0.
}
}
class ByteStream(ByteStreamAdapter)
{
method close
{
if (self.bsobj notNil)
{
self.bsobj close.
self.bsobj := nil.
}.
}
}
class TextStream(ByteStream)
{
} }

View File

@ -5034,8 +5034,8 @@ static int compile_expression_primary (moo_t* moo, const moo_oocs_t* ident, cons
switch (TOKEN_TYPE(moo)) switch (TOKEN_TYPE(moo))
{ {
case MOO_IOTOK_IDENT_DOTTED: case MOO_IOTOK_IDENT_DOTTED:
ident_dotted = 1;
case MOO_IOTOK_IDENT: case MOO_IOTOK_IDENT:
ident_dotted = (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED);
ident = TOKEN_NAME(moo); ident = TOKEN_NAME(moo);
ident_loc = TOKEN_LOC(moo); ident_loc = TOKEN_LOC(moo);
read_next_token = 1; read_next_token = 1;

View File

@ -592,11 +592,11 @@ static moo_pfinfo_t pfinfos[] =
{ I, { 'c','o','n','n','e','c','t',':','\0' }, 0, { pf_connect_socket, 1, 1 } }, { I, { 'c','o','n','n','e','c','t',':','\0' }, 0, { pf_connect_socket, 1, 1 } },
{ I, { 'l','i','s','t','e','n',':','\0' }, 0, { pf_listen_socket, 1, 1 } }, { I, { 'l','i','s','t','e','n',':','\0' }, 0, { pf_listen_socket, 1, 1 } },
{ I, { 'o','p','e','n','\0' }, 0, { pf_open_socket, 1, 3 } }, { I, { 'o','p','e','n','\0' }, 0, { pf_open_socket, 1, 3 } },
{ I, { 'r','e','a','d','B','y','t','e','s',':','\0' }, 0, { pf_read_socket, 1, 1 } }, { I, { 'r','e','a','d','B','y','t','e','s','I','n','t','o',':','\0' }, 0, { pf_read_socket, 1, 1 } },
{ I, { 'r','e','a','d','B','y','t','e','s',':','o','f','f','s','e','t',':','l','e','n','g','t','h',':','\0' }, 0, { pf_read_socket, 3, 3 } }, { I, { 'r','e','a','d','B','y','t','e','s','I','n','t','o',':','o','f','f','s','e','t',':','l','e','n','g','t','h',':','\0' }, 0, { pf_read_socket, 3, 3 } },
{ I, { 's','o','c','k','e','t','E','r','r','o','r','\0' }, 0, { pf_get_socket_error, 0, 0 } }, { I, { 's','o','c','k','e','t','E','r','r','o','r','\0' }, 0, { pf_get_socket_error, 0, 0 } },
{ I, { 'w','r','i','t','e','B','y','t','e','s',':','\0' }, 0, { pf_write_socket, 1, 1 } }, { I, { 'w','r','i','t','e','B','y','t','e','s','F','r','o','m',':','\0' }, 0, { pf_write_socket, 1, 1 } },
{ I, { 'w','r','i','t','e','B','y','t','e','s',':','o','f','f','s','e','t',':','l','e','n','g','t','h',':','\0' }, 0, { pf_write_socket, 3, 3 } } { I, { 'w','r','i','t','e','B','y','t','e','s','F','r','o','m',':','o','f','f','s','e','t',':','l','e','n','g','t','h',':','\0' }, 0, { pf_write_socket, 3, 3 } }
}; };
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */