internalinlinefunRealBufferedSource.commonIndexOf(b:Byte,fromIndex:Long,toIndex:Long):Long{varfromIndex=fromIndexcheck(!closed){"closed"}require(fromIndexin0L..toIndex){"fromIndex=$fromIndex toIndex=$toIndex"}while(fromIndex<toIndex){//调用buffer的indexOfvalresult=buffer.indexOf(b,fromIndex,toIndex)if(result!=-1L)returnresult// The byte wasn't in the buffer. Give up if we've already reached our target size or if the// underlying stream is exhausted.vallastBufferSize=buffer.sizeif(lastBufferSize>=toIndex||source.read(buffer,Segment.SIZE.toLong())==-1L)return-1L// Continue the search from where we left off.fromIndex=maxOf(fromIndex,lastBufferSize)}return-1L}
overridefunreadString(byteCount:Long,charset:Charset):String{require(byteCount>=0&&byteCount<=Integer.MAX_VALUE){"byteCount: $byteCount"}if(size<byteCount)throwEOFException()if(byteCount==0L)return""vals=head!!if(s.pos+byteCount>s.limit){// If the string spans multiple segments, delegate to readBytes().//调用readByteArrayreturnString(readByteArray(byteCount),charset)}valresult=String(s.data,s.pos,byteCount.toInt(),charset)s.pos+=byteCount.toInt()size-=byteCountif(s.pos==s.limit){head=s.pop()SegmentPool.recycle(s)}returnresult}
internalinlinefunBuffer.commonWriteUtf8(string:String,beginIndex:Int,endIndex:Int):Buffer{require(beginIndex>=0){"beginIndex < 0: $beginIndex"}require(endIndex>=beginIndex){"endIndex < beginIndex: $endIndex < $beginIndex"}require(endIndex<=string.length){"endIndex > string.length: $endIndex > ${string.length}"}// Transcode a UTF-16 Java String to UTF-8 bytes.vari=beginIndexwhile(i<endIndex){varc=string[i].codewhen{c<0x80->{valtail=writableSegment(1)valdata=tail.datavalsegmentOffset=tail.limit-ivalrunLimit=minOf(endIndex,Segment.SIZE-segmentOffset)// Emit a 7-bit character with 1 byte.data[segmentOffset+i++]=c.toByte()// 0xxxxxxx// Fast-path contiguous runs of ASCII characters. This is ugly, but yields a ~4x performance// improvement over independent calls to writeByte().while(i<runLimit){c=string[i].codeif(c>=0x80)breakdata[segmentOffset+i++]=c.toByte()// 0xxxxxxx}valrunSize=i+segmentOffset-tail.limit// Equivalent to i - (previous i).tail.limit+=runSizesize+=runSize.toLong()}c<0x800->{// Emit a 11-bit character with 2 bytes.valtail=writableSegment(2)/* ktlint-disable no-multi-spaces */tail.data[tail.limit]=(cshr6or0xc0).toByte()// 110xxxxxtail.data[tail.limit+1]=(cand0x3for0x80).toByte()// 10xxxxxx/* ktlint-enable no-multi-spaces */tail.limit+=2size+=2Li++}c<0xd800||c>0xdfff->{// Emit a 16-bit character with 3 bytes.valtail=writableSegment(3)/* ktlint-disable no-multi-spaces */tail.data[tail.limit]=(cshr12or0xe0).toByte()// 1110xxxxtail.data[tail.limit+1]=(cshr6and0x3for0x80).toByte()// 10xxxxxxtail.data[tail.limit+2]=(cand0x3for0x80).toByte()// 10xxxxxx/* ktlint-enable no-multi-spaces */tail.limit+=3size+=3Li++}else->{// c is a surrogate. Make sure it is a high surrogate & that its successor is a low// surrogate. If not, the UTF-16 is invalid, in which case we emit a replacement// character.vallow=(if(i+1<endIndex)string[i+1].codeelse0)if(c>0xdbff||low!in0xdc00..0xdfff){writeByte('?'.code)i++}else{// UTF-16 high surrogate: 110110xxxxxxxxxx (10 bits)// UTF-16 low surrogate: 110111yyyyyyyyyy (10 bits)// Unicode code point: 00010000000000000000 + xxxxxxxxxxyyyyyyyyyy (21 bits)valcodePoint=0x010000+(cand0x03ffshl10or(lowand0x03ff))// Emit a 21-bit character with 4 bytes.valtail=writableSegment(4)/* ktlint-disable no-multi-spaces */tail.data[tail.limit]=(codePointshr18or0xf0).toByte()// 11110xxxtail.data[tail.limit+1]=(codePointshr12and0x3for0x80).toByte()// 10xxxxxxtail.data[tail.limit+2]=(codePointshr6and0x3for0x80).toByte()// 10xxyyyytail.data[tail.limit+3]=(codePointand0x3for0x80).toByte()// 10yyyyyy/* ktlint-enable no-multi-spaces */tail.limit+=4size+=4Li+=2}}}}returnthis}
internalinlinefunBuffer.commonCompleteSegmentByteCount():Long{varresult=sizeif(result==0L)return0L// Omit the tail if it's still writable.valtail=head!!.prev!!if(tail.limit<Segment.SIZE&&tail.owner){result-=(tail.limit-tail.pos).toLong()}returnresult}